I have a application in react.js and it's server is in spring boot.
Now I want to implement OAuth2 for user authentication. If user is authenticated, then app can get response from the server.
In my application.properties I have added these:
spring.security.oauth2.client.registration.github.client-id=somekey
spring.security.oauth2.client.registration.github.client-secret=somekeyhere`
In pom.xml I have added these:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
</dependency>
I have create WebSecurityConfiguration like this:
#Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.oauth2Login();
}
}
When I try to get any requests like /user in browser it redirects me to login or to create account and everything works fine.
But the problem is I can't use the react.js application anymore, so how can I make the authentication in client portion?
Related
I working on React app which is secured by Okta OAuth provider. Currently, all of my routes are authenticated. I want a public route where anyone can access it. Eg: https://my.example.com/welcome
These are the configs that I have used
application.yml
okta:
oauth2:
issuer: https://xxxxxxxxx.okta.com/oauth2/default
clientId: xxxxxxxxxxxxxx
clientSecret: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
post-logout-redirect-uri: /
redirect-uri: /login/callback
Spring security config
httpSecurity.authorizeRequests()
.antMatchers("/", "/welcome").permitAll()
.anyRequest().authenticated()
.and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.and().oauth2Client()
.and().oauth2Login();
return httpSecurity.build();
React Route
<Route path={"/welcome"} exact={true} render={(props) => (<WelcomePage/>)}/>
When I visit /welcome route I'm getting a blank page with this warning message in the browser
Cross-Origin Read Blocking (CORB) blocked cross-origin response https://xxxxxxx.okta.com/oauth2/default/v1/authorize?response_type=code&client_id=xxxxxxxxx&scope=profile%20email%20openid&state=rDYLqV7WDv2la1onSvQsTNeXCvDmWhS0_ZoPFlMAE80%3D&redirect_uri=https://xxxxxx.xxxxx.com/careportal/login/callback&nonce=XvMoC5iP5OGYsvG0bS-QfQh1yfYmhNohmD7GvfukyCo with MIME type text/html. See https://www.chromestatus.com/feature/5629709824032768 for more details.
Can anyone help me to access a public route without auth?
TIA
If you have anything else than spring-boot-starter-oauth2-resource-server as OAuth2 lib in your Spring project, remove it and configure your Spring REST API as a resource-server.
With the helper lib from second tutorial, this might be enough:
<dependency>
<groupId>com.c4-soft.springaddons</groupId>
<!-- replace "webmvc" with "weblux" for reactive app -->
<!-- replace "jwt" with "introspecting" if Okta access-tokens are not JWTs -->
<artifactId>spring-addons-webmvc-jwt-resource-server</artifactId>
<version>6.0.4</version>
</dependency>
#EnableMethodSecurity // replace with #EnableReactiveMethodSecurity for reactive app
#Configuration
public class SecurityConfig {
}
com.c4-soft.springaddons.security.issuers[0].location=https://xxxxxxxxx.okta.com/
com.c4-soft.springaddons.security.issuers[0].authorities.claims=groups
com.c4-soft.springaddons.security.permit-all=/,/welcome
# following might be too permissive, restrict if needed
com.c4-soft.springaddons.security.cors[0].path=/**
With Spring spring-boot-starter-oauth2-resource-server only, there is quite some more Java conf to write (refer to first tutorial)
Do not forget to request groups (and maybe openid and offline_access) scopes when you authenticate users from your React app or other clients like Postman.
Im working on uploading images with spring but I get error when I try save file in one of my projects folder.
Errors:
java.nio.file.NoSuchFileException: \resources\images\photo001.png
There was an unexpected error (type=Internal Server Error, status=500).
\resources\images\photo001.png
I have this path:
String path = "\\resources\\images\\";
String path2 = "c:\\temp\\";
Path2 works but I would like to save my files in project without passing whole path starting from C:...
What pass should I pass to save it in resources/images in my project?
My project looks like that:
https://i.imgur.com/Dn6wXAK.png
Try 'images/'
All files in src/main/resources are copied into classes/ so in your jar or war there is no folder /resources.
You also should not use the windows specific backslash '\' instead use the
Use /images/ instead this makes your build portable so it can run on Linux also.
Senio, if you are using Spring Boot then there is a project called Spring Content that will allow you to create an image store in very few lines of code.
All you would need to do is add the following Spring Content dependencies (assuming maven):-
<dependencies>
<!-- Standard Spring Boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.3</version>
</dependency>
<!-- Spring Content -->
<dependency>
<groupId>com.github.paulcwarren</groupId>
<artifactId>spring-content-fs-boot-starter</artifactId>
<version>0.0.10</version>
</dependency>
<dependency>
<groupId>com.github.paulcwarren</groupId>
<artifactId>spring-content-rest-boot-starter</artifactId>
<version>0.0.10</version>
</dependency>
</dependencies>
In your Spring Boot Application class, create an ImageStore interface. Annotate it as a REST resource. This causes Spring Content to inject an implementation (of this interface for the filesystem) as well as REST endpoints saving you from having to write any this code yourself:-
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
#StoreRestResource(path="images")
public interface ImageStore extends Store<String> {}
}
By default Spring Content FS will create a store under java.io.tmpdir. So you will also need to set the SPRING_CONTENT_FS_FILESYSTEM_ROOT environment variable to point to the root of your "store"; c:\temp\resources\images.
Start the application and you will be able to upload images by POSTing (or PUTting) to:-
/images/some/path/image-1.jpg
(This also supports GET (download) and DELETE.)
You'll find uploaded images under c:\temp\resources\images\some\path\image-1.jpg
HTH
I have a Spring boot and it has some services running on it. It also has a react view that has its own routing. Is this even possible, can I have a backend routing and front end routing within the same server?
Thanks
After some research, front-end routing is a misleading term, although it is being widely used. The routing needs to always go to the back-end, and the back-end decides what happens with the request. If React.js, Angular or any other front-end frameworks are handling routing, back-end needs to forward all the requests that are coming from the front-end to the front-end again, which is the HTML page that has the JS and CSS. To achieve this with spring framework, I used a tuckey filter to forward requests to the html page. The magic word is FORWARDING the request to the html page.
The urlrewrite.xml for the tuckey filter forwards the requests to the ui again, it looks like:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 4.0//EN" "http://www.tuckey.org/res/dtds/urlrewrite4.0.dtd">
<!-- Configuration file for UrlRewriteFilter http://www.tuckey.org/urlrewrite/ -->
<urlrewrite>
<rule match-type="regex">
<name>Front-end forwarding</name>
<note>Forwarding all routes from the front-end to the ui controller</note>
<condition type="request-uri" operator="notequal">^\/([\-\w\.]+)([\-/\w\.]*)(\.([\-\w]+))$</condition>
<from>^\/ui\/([/\-\w]+)$</from>
<to type="forward" last="true">/ui</to> <!--This is where the ui controller is located-->
</rule>
</urlrewrite>
This is the tuckey filter java configurations:
#Component
public class TuckeyFilterConfigurations extends UrlRewriteFilter{
private static final String CONFIG_LOCATION = "classpath:/urlrewrite.xml";
#Value(CONFIG_LOCATION)
private Resource resource;
#Override
protected void loadUrlRewriter(FilterConfig filterConfig) throws ServletException {
try {
Conf conf = new Conf(filterConfig.getServletContext(), resource.getInputStream(), resource.getFilename(), "");
checkConf(conf);
} catch (IOException ex) {
throw new ServletException("Unable to load URL-rewrite configuration file from " + CONFIG_LOCATION, ex);
}
}
}
And finally, the controller that serves the html page simply looks like:
#Controller
public class UiController {
#RequestMapping("/ui")
public String entrance(){
return "index.html";
}
}
Yes you can have but it's always a good practice to have the routing logic at one place, as it helps a lot in troubleshooting the application once it's size grows.
How this would work, can you give an example? When I have a front end routing to a certain link, it is always directed to the backend. I know that there is the # routing, but I'm looking for a solution for the regular "/" routing?
You can use BrowserRouter or StaticRouter to achieve it. Here is the nice guide by React training team to implement Server Rendering using StaticRouter - Server Rendering with React.
Step 1 add below in your pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
Step 2, Please add below two lines in your application.properties :
#reload static content lively without reboot spring boot app
spring.devtools.livereload.enabled: true
#specify the static file location
spring.resources.static-locations: file:${your-frontend-file-root-location}
I'm new to Spring Boot and struggling to deploy a simple HTML web app (AngularJS) to Tomcat 8. This web app simply serves some HTML/CSS/JS content with no REST calls to a backend. It has been "compiled" using Webpack -- this produces JS/CSS bundles and a single index.html file that points to them via <script> / <link> tags -- and has been tested on ExpressJS and Spring Boot w/ Embedded tomcat and works as expected. But going down the path of a stand-alone WAR and deploying to Tomcat 8 does not seem to work properly.
For the Spring Boot project, I've included all the HTML/CSS/JS files in the src/main/resources/public folder (no subfolders) and have also configured the pom.xml as follows (basic config):
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.my-app</groupId>
<artifactId>my-app</artifactId>
<version>0.0.1</version>
<packaging>war</packaging>
<name>my-app</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
"Main" class:
package com.example.my.app;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
#SpringBootApplication
public class MyAppApplication extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(MyAppApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(MyAppApplication.class, args);
}
}
Here are the steps I used to do the Tomcat deployment:
mvn clean package to generate the WAR
Copy the WAR to path/to/tomcat8/webapp
Start Tomcat
http://localhost:8080/my-app => auto-loads index.html
Unfortunately all I see are 404 errors because it couldn't find some JS/CSS file. Is there a config I'm missing?
Updated:
Here is the index.html file (auto-generated via Webpack):
<!doctype html>
<html>
<head>
<base href="/">
<meta charset="utf-8">
<title>My App</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<link rel="icon" type="image/png" href="./assets/images/favicon.ico" />
<link href="/main-aa49893f83cc830596563d81f09a9611.css" rel="stylesheet"><link href="/main-5949f1f257a55a77e48bc4ab62fbc99a.css" rel="stylesheet"></head>
<body ng-app="myapp">
<ui-view></ui-view>
<script type="text/javascript" src="vendor-353ddb48f4ffe6546d59.js"></script><script type="text/javascript" src="app-353ddb48f4ffe6546d59.js"></script></body>
</html>
Here are the errors I'm seeing in Chrome Web Inspector when visiting localhost:8080/my-app/index.html:
http://localhost:8080/main-5949f1f257a55a77e48bc4ab62fbc99a.css Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8080/main-aa49893f83cc830596563d81f09a9611.css Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8080/vendor-4ba9083ed9802279c207.js Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8080/app-4ba9083ed9802279c207.js Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8080/vendor-4ba9083ed9802279c207.js Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8080/app-4ba9083ed9802279c207.js Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8080/main-aa49893f83cc830596563d81f09a9611.css Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8080/main-5949f1f257a55a77e48bc4ab62fbc99a.css Failed to load resource: the server responded with a status of 404 (Not Found)
One more thing I forgot to mention. When I generate the war using mvn clean package, all the files that are under src/main/resources/public are placed into the WEB-INF/classes/resource subfolder. According to research, these files are not publicly visible (i.e. if I try to access localhost:8080/my-app/foo.css, it'll give 404). Is this why the index.html file is unable to "see" the JS/CSS files it depends on?
I ended up figuring it out but not using Spring Boot to package the WAR file. There was another project lying around on my local that used plain old Maven + pom.xml + web.xml to create WARs, which I used as a reference to figure out why the current project was not working. There were multiple issues:
When you deploy onto Tomcat 8 using default config, it will append the name of the WAR file (what they refer to as Context) to its path. In this case, it was http://localhost:8080/my-app. The "compiled" AngularJS app's index.html had a <base href="/"> tag that needed to point to /my-app/ instead of /. This was the main reason why the JS/CSS files were not visible in Web Inspector > Sources.
<link> tag's src attribute was not supposed to contain a leading /
In the case of the Spring Boot App I posted above, it comes with an Embedded Tomcat and deploys the app at the Root Context so there's no need to change any paths in the index.html file.
Similar to Spring Boot, I also had no issues running the app in ExpressJS since a "sub-context" was not created. Again, there was no need to modify any files in this case.
There were other errors related to finding resources like .ttf files but at least the app was able to run.
Update:
Looks like its possible to serve the WAR file from the Tomcat 8 root by adding the following near the bottom of the server.xml file:
<Context path="" docBase="my-app" debug="0" reloadable="true"></Context>
This will prevent the need to modify the index.html file.
Awesome :)
The most common issue with the setup you have described, without more context, is that you are most likely using absolute URLs to point at your js / css files. As such when you put them into the servlet container under /my-app they no longer reference properly as they are trying to go to the root /. You need to use relative URLs when describing the location of the resource files on the path.
I had the same problem, and it is related to Webpack more than to Spring-boot.
In your webpack.common.js / webpack.prod.js you have to set :
metada.baseUrl = './';
and inject this in your <base> link in index.html
And you also have to set
output.publicPath: './'
With both variable set, this worked for me.
Uhmm i've tried some of this on my spring-boot project.
First i'd add a dependency on my project pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
then i'd add an index.html on src/main/resources/templates
after that you should add a controller to point to that index
#Controller
public class AppController {
#RequestMapping("/")
String index() {
return "index";
}
}
For more information see this guide. Spring-boot and Thymeleaf
I implement *.vm template in my routing application (Servicemix)
but after deploying JAR archive I get this error
karaf#root> Exception in thread "SpringOsgiExtenderThread-38" org.apache.camel.RuntimeCamelException: org.apache.camel.FailedToCreateRouteException:
Failed to create route route14 at: >>> To[velocity:getPayments.vm] <<< in route: Route(route14)[[From[direct:start]] -> [To[velocity:getPayme...
because of Failed to resolve endpoint: velocity://getPayments.vm due to:
No component found with scheme: velocity
I followed this manual
http://camel.apache.org/tutorial-example-reportincident-part4.html
and pointed camel-velocity in pom.xml with same camel-core version
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>2.13.1</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-velocity</artifactId>
<version>2.13.1</version>
</dependency>
Does anybody know, what the matter is ?
As you are using Karaf you need to add the velocity feature:
feature:install camel-velocity
Or if using Karaf 4.x
feature:install camel-velocity
nothing changed even after ServiceMix restarting, but I found solution.
after init-ing of CamelContext I add camel components manually.
import org.apache.camel.component.velocity.*;
import org.apache.camel.component.spring.ws.*;
....
private CamelContext camel;
.....
camel = new DefaultCamelContext();
camel.addComponent("velocity", new VelocityComponent());
camel.addComponent("spring-ws",new SpringWebserviceComponent());