OAuth2ClientAuthenticationProcessingFilter get token - oauth-2.0

How can I get token from backend java server
I have a oauth server authentication and I can login successfully with Spring security layer. I get toke in web browser client via http get request...
https://x.x.x.x/oxauth/restv1/token
How can I get token in backend part using OAuth2ClientAuthenticationProcessingFilter class?
/**
* Called after executed Configuration "addFilterBefore"
*
* #return OAuth2ClientAuthenticationProcessingFilter
*/
private OAuth2ClientAuthenticationProcessingFilter oauthFilter() {
OAuth2ClientAuthenticationProcessingFilter oauthFilter = new OAuth2ClientAuthenticationProcessingFilter("/login");
// OAuth2RestTemplate > Spring Boot does not automatically create such a bean,
OAuth2RestTemplate oauthTemplate = new OAuth2RestTemplate(oauth(), oauth2ClientContext);
UserInfoTokenServices tokenServices = new UserInfoTokenServices(oauthResource().getUserInfoUri(), oauth().getClientId());
tokenServices.setRestTemplate(oauthTemplate);
oauthFilter.setRestTemplate(oauthTemplate);
oauthFilter.setTokenServices(tokenServices);
return oauthFilter;
}

I found a way to do that... oauthApplication.getOauth2ClientContext().getAccessToken()

Related

Spring Cloud Gateway Getting a 500 Exception while trying to refresh_token using expired access_token and refresh_token

I have a secured Spring Cloud Gateway application using ServerHttpSecurity.oauth2Login() that can successfully renew expired access tokens using the refresh token. However, when the refresh token also expires and the application tries to renew the access token with it, I get a 500 Internal Server Error [seems to be caused by a 400 Bad Request error just before it] with the following exception:
org.springframework.security.oauth2.client.ClientAuthorizationException: [invalid_grant] Token is not active
at org.springframework.security.oauth2.client.RefreshTokenReactiveOAuth2AuthorizedClientProvider.lambda$authorize$0(RefreshTokenReactiveOAuth2AuthorizedClientProvider.java:97) ~[spring-security-oauth2-client-5.4.1.jar:5.4.1]
Full logs here: https://github.com/spring-projects/spring-security/files/8319348/logs.txt
Only if I re-issue the request (refresh browser with the call to the secured endpoint), I will get redirected to the login page (desired behavior).
While debugging, I noticed that re-issuing the request after the 500 Internal Server Error under the hood results in the following exception:
org.springframework.security.oauth2.client.ClientAuthorizationRequiredException: [client_authorization_required] Authorization required for Client Registration Id: <client-id>.
and that is probably what causes the redirect to the login page.
Request execution details here
My question: Can I avoid getting the 500 Internal Server Error and instead be redirected to the login page? If yes, how can I accomplish that?
Environment details
Spring Boot: 2.4.0
Spring Cloud: 2020.0.0
Spring Security: 5.4.1
The solution was to catch the 500 caused while refreshing a token and then initiating a new authorization flow, using the next classes:
import org.springframework.security.oauth2.client.*;
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
import org.springframework.security.oauth2.client.web.DefaultReactiveOAuth2AuthorizedClientManager;
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
import org.springframework.util.Assert;
import reactor.core.publisher.Mono;
/**
* A delegating implementation of ReactiveOAuth2AuthorizedClientManager to help deal with a 500 Internal Server Error
* that is a result of an expired access token. With ReactiveOAuth2AuthorizedClientManagerCustom, we manage to redirect
* to the login page instead of returning a 500 Internal Server Error to the user/client.
*/
public class ReactiveOAuth2AuthorizedClientManagerCustom implements ReactiveOAuth2AuthorizedClientManager {
private final ReactiveClientRegistrationRepository clientRegistrationRepository;
private final ServerOAuth2AuthorizedClientRepository authorizedClientRepository;
private final ReactiveOAuth2AuthorizedClientManager authorizedClientManager;
public ReactiveOAuth2AuthorizedClientManagerCustom(ReactiveClientRegistrationRepository clientRegistrationRepository,
ServerOAuth2AuthorizedClientRepository authorizedClientRepository) {
this.clientRegistrationRepository = clientRegistrationRepository;
this.authorizedClientRepository = authorizedClientRepository;
this.authorizedClientManager = new DefaultReactiveOAuth2AuthorizedClientManager(
this.clientRegistrationRepository, this.authorizedClientRepository
);
}
public Mono<OAuth2AuthorizedClient> authorize(OAuth2AuthorizeRequest authorizeRequest) {
Assert.notNull(authorizeRequest.getClientRegistrationId(), "Client registration id cannot be null");
return this.authorizedClientManager.authorize(authorizeRequest)
// The token has expired, therefore we initiate a new grant flow
.onErrorMap(
ClientAuthorizationException.class,
error -> new ClientAuthorizationRequiredException(authorizeRequest.getClientRegistrationId())
);
}
}
And then adding the next #Bean
public ReactiveOAuth2AuthorizedClientManagerCustomConfig(ReactiveClientRegistrationRepository clientRegistrationRepository,
ServerOAuth2AuthorizedClientRepository authorizedClientRepository) {
this.clientRegistrationRepository = clientRegistrationRepository;
this.authorizedClientRepository = authorizedClientRepository;
}
#Bean
#Primary
ReactiveOAuth2AuthorizedClientManager authorizedClientManager() {
return new ReactiveOAuth2AuthorizedClientManagerCustom(
this.clientRegistrationRepository, this.authorizedClientRepository
);
}

How to achieve secure REST api along with springboot session and spring security without authentication

Problem: My java springboot application receives JWT token from external system to authenticate a user with their external identity management provider which returns the user details upon success.
Once userdetails is received, the backend application must create a redirect url for the external system end user. The redirect url will land the user on my angular application to show the landing page.
Here on, all the rest api's should be allowed through an http session.
In case the user tries to access the rest api's directly, he should get an Authentication error.
How can we achieve authorization in this case since authentication was not done by my spring boot application. Can we create custom Spring session using spring security and manually put userDetails in the SecurityContext?
I am currently dealing JWT tokens obtained from Google. Including Google, pretty much all authorization servers provide rest APIs such as GET /userInfo, where you can carry the JWT token in the request header or in the URL as a GET parameter, and then verify if the JWT token is valid, non-expired, etc.
Because verifying a JWT token is usually stateless, these APIs generally come with a generous limit and you can call them as many times as you need.
I assume that you have Spring security integrated and then you can add a filter. In this way, every request has to be verified for its token in the header.
#Service
public class TokenAuthenticationFilter extends OncePerRequestFilter {
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
try {
String header = request.getHeader("Authorization");
RestTemplate restTemplate = new RestTemplate(); // If you use Google SDK, xxx SDK, you do not have to use restTemplate
String userInfoUrl = "https://example.com/api/userInfo";
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", header);
HttpEntity entity = new HttpEntity(headers);
ResponseEntity<String> response = restTemplate.exchange(
userInfoUrl, HttpMethod.GET, entity, String.class, param);
User user = response.getBody(); // Get your response and figure out if the Token is valid.
// If the token is valid? Check it here....
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
} catch (Exception ex) {
logger.error("Could not set user authentication in security context", ex);
}
filterChain.doFilter(request, response);
}
}

Swagger UI - getting the CORS issue when bearer authorization token is wrong (server responds with 403), works fine in case of correct token

I am documenting APIs using swagger openApi 3.0.0. And I am using bearer authentication provided by the swagger itself. Now when the authorization token is correct, server sends the response and it is getting displayed over the swagger UI, but when token is incorrect, server sends the 403 forbidden error and swagger just displays "TypeError: Failed to fetch". I have attached the screenshots of browser's network tab stuff.
OPTIONS with sending 200 response
getting the Access-control-allow-origin: * from the OPTIONS response
getting the server response 403 as the authorization token is wrong
but not getting Access control allow origin response in the actual response.. so getting the CORS issue
This is my swaggerConfig.java code
#Bean
public Docket swagger() {
return new Docket(DocumentationType.SWAGGER_12)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
/**
* #param defaultResourcesProvider
* #return swaggerResource for documenting the APIs
*/
#Primary
#Bean
public SwaggerResourcesProvider swaggerResourcesProvider(
InMemorySwaggerResourcesProvider defaultResourcesProvider) {
return () -> {
List<SwaggerResource> resources = new ArrayList<>();
Arrays.asList(<list of APIs>)
.forEach(resourceName -> resources.add(loadResource(resourceName)));
return resources;
};
}
private SwaggerResource loadResource(String resource) {
String file_name = "swagger.yaml";
SwaggerResource swaggerResource = new SwaggerResource();
swaggerResource.setName(resource);
swaggerResource.setLocation("/swagger-apis/" + resource + "/" + file_name);
return swaggerResource;
}
and in the swagger.yaml file for one of the APIs, I have used securityschema as follows:
security:
- bearerAuth: []
securitySchemes:
bearerAuth:
type: http
scheme: bearer

Unable to call nuxeo rest api from rest client when integrated with Keycloak authentication plugin

I wanted to integrate keycloak as authentication plugin for nuxeo platform both running on my local machine
Set up details
Nuxeo platform version: 10.10 (runs on tomcat 9)
Keycloak version: 6.0.1
keycloak tomcat adapter distribution: keycloak-tomcat8-adapter-dist
I followed the steps mentioned in link https://github.com/nuxeo/nuxeo/tree/master/nuxeo-services/login/nuxeo-platform-login-keycloak.
Here, I built the nuxeo-platform-login-keycloak plugin for keycloak 6.0.1 version.
On keycloak,
I set up a auth client under newly created realm 'demo'
Client details available in
client configuration
I created role as 'Members' and added admin role to it
I created a user 'keycloakuser' and added to 'Members'.
When nuxeo ui is hit from browser, the authentication flow works fine. It redirects me to login page of keycloak, on valid credentials, it redirects me to nuxeo ui.
The user created along with 'Members' group assigned to it.
Error Scenario
To call rest api from postman, I configured Oauth2 for authentication.
Auth url: http://localhost:8080/auth/realms/demo/protocol/openid-connect/auth
Token Url: http://localhost:8080/auth/realms/demo/protocol/openid-connect/token
Client: testclient
Client secret: *****
Scope: openid
I used access_token obtained using Oauth2 flow, to make API call as http://localhost:8190/nuxeo/api/v1/id/document_id. It is failing with
java.lang.ClassCastException: class org.apache.catalina.core.ApplicationHttpRequest cannot be cast to class org.apache.catalina.connector.RequestFacade (org.apache.catalina.core.ApplicationHttpRequest and org.apache.catalina.connector.RequestFacade are in unnamed module of loader java.net.URLClassLoader #39aeed2f)
at org.nuxeo.ecm.platform.ui.web.keycloak.DeploymentResult.invokeOn(DeploymentResult.java:79) [nuxeo-platform-login-keycloak-10.10.jar:?]
at org.nuxeo.ecm.platform.ui.web.keycloak.KeycloakAuthenticatorProvider.provide(KeycloakAuthenticatorProvider.java:56) [nuxeo-platform-login-keycloak-10.10.jar:?]
at org.nuxeo.ecm.platform.ui.web.keycloak.KeycloakAuthenticationPlugin.handleRetrieveIdentity(KeycloakAuthenticationPlugin.java:113) [nuxeo-platform-login-keycloak-10.10.jar:?]
at org.nuxeo.ecm.platform.ui.web.auth.NuxeoAuthenticationFilter.handleRetrieveIdentity(NuxeoAuthenticationFilter.java:1137) [nuxeo-platform-web-common-10.10.jar:?]
at org.nuxeo.ecm.platform.ui.web.auth.NuxeoAuthenticationFilter.doFilterInternal(NuxeoAuthenticationFilter.java:548) [nuxeo-platform-web-common-10.10.jar:?]
Observation:
1. The API request call is not hitting the keycloak endpoint
2. I tried to print the reqqest type (actually the request wrapper type) in both scenarios.
For browser request, it was org.apache.catalina.connector.RequestFacade and for api request it was org.apache.catalina.core.ApplicationHttpRequest which is not extending org.apache.catalina.connector.RequestFacade
Questions:
1. Does above behavior (mentioend in point 2) differ in tomcat versions earlier to tomcat 9?
2. Is the problem with compatibility issues with tomcat version and keycloak adapters jar version?
Late answer, but it may come handy for new readers. I had the exact same issue some months ago. It seems to be due to a bug in the nuxeo-platform-login-keycloak plugin.
I endend making the following changes to org.nuxeo.ecm.platform.ui.web.keycloak.DeploymentResult:
public class DeploymentResult {
final static Logger LOGGER = LoggerFactory.getLogger(DeploymentResult.class);
private boolean isOk;
private static KeycloakDeployment keycloakDeployment;
private HttpServletRequest httpServletRequest;
private HttpServletResponse httpServletResponse;
private Request request;
private CatalinaHttpFacade facade;
public DeploymentResult(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
this.httpServletRequest = httpServletRequest;
this.httpServletResponse = httpServletResponse;
}
boolean isOk() {
return isOk;
}
public static KeycloakDeployment getKeycloakDeployment() {
return keycloakDeployment;
}
public Request getRequest() {
return request;
}
public CatalinaHttpFacade getFacade() {
return facade;
}
public DeploymentResult invokeOn(AdapterDeploymentContext deploymentContext) {
// In Tomcat, a HttpServletRequest and a HttpServletResponse are wrapped in a Facades
if (httpServletRequest instanceof RequestFacade) {
// Received upon logout.
request = unwrapRequest(httpServletRequest);
} else {
request = unwrapRequest(((ServletRequestWrapper) httpServletRequest).getRequest());
}
facade = new CatalinaHttpFacade(httpServletResponse, request);
if (keycloakDeployment == null) {
keycloakDeployment = deploymentContext.resolveDeployment(facade);
}
if (keycloakDeployment.isConfigured()) {
isOk = true;
return this;
}
isOk = false;
return this;
}
/**
* Get the wrapper {#link Request} hidden in a {#link ServletRequest} object
*
* #param servletRequest, the main ServletRequest object
* #return the wrapper {#link Request} in {#link ServletRequest}
*/
private Request unwrapRequest(final ServletRequest servletRequest) {
try {
final Field f = servletRequest.getClass().getDeclaredField("request");
f.setAccessible(true); // grant access to (protected) field
return (Request) f.get(servletRequest);
} catch (final NoSuchFieldException | IllegalAccessException e) {
LOGGER.error("Couldn't unwrap request", e);
throw new RuntimeException(e);
} catch (final Exception e) {
LOGGER.error("Couldn't unwrap request", e);
throw e;
}
}
}
After building and deploying the plugin with these changes, I was allowed to call Nuxeo's REST API with bearer authentication using access token obtained through Keycloak.
Disclaimer: I focused on making it work, not on making it clean...

Integrate Spring Security OAuth2 and Spring Social

I'm working with a Spring Boot + Spring Security OAuth2 application that I believe was inspired by examples from Dave Syer. The application is configured to be an OAuth2 authorization server, with a single public client using the Resource Owner Password Credentials flow. A successful token is configured to be a JWT.
The public Angular client sends a POST request to /oauth/token with a basic auth header containing the client id and secret (this was the easiest way to get the client to authenticate, even though the secret is not private). The body of the request contains username, password, and grant type of "password".
In addition to being an authentication server, the application is a RESTful resource server for users, teams, and organizations.
I'm trying to add an additional SSO authentication flow using Spring Social. I've got Spring Social configured to authenticate through external providers via /auth/[provider]; however, following requests no longer have the SecurityContext correctly set. Possibly, Spring Security OAuth server or client is overriding the SecurityContext?
If I can get the SecurityContext correctly set after the Spring Social flow, I've got a new TokenGranter that allows a new grant type of "social" that would check the SecurityContextHolder for the pre authenticated user.
I'm interested in both a solution to my specific problem with the SecurityContext (I believe it's an issue with Spring OAuth + Social integration), or a different approach for authenticating with external providers and getting a valid JWT from our own auth server.
Thanks!
I had a similar problem on a JHipster-generated web application. Finally I decided to go with the SocialAuthenticationFilter option from Spring Social (via the SpringSocialConfigurer). After a successful social login, the server automatically generates and returns the "own" access token via redirection to the client app.
Here's my try:
#Configuration
#EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter implements EnvironmentAware {
//...
#Inject
private AuthorizationServerTokenServices authTokenServices;
#Override
public void configure(HttpSecurity http) throws Exception {
SpringSocialConfigurer socialCfg = new SpringSocialConfigurer();
socialCfg
.addObjectPostProcessor(new ObjectPostProcessor<SocialAuthenticationFilter>() {
#SuppressWarnings("unchecked")
public SocialAuthenticationFilter postProcess(SocialAuthenticationFilter filter){
filter.setAuthenticationSuccessHandler(
new SocialAuthenticationSuccessHandler(
authTokenServices,
YOUR_APP_CLIENT_ID
)
);
return filter;
}
});
http
//... lots of other configuration ...
.apply(socialCfg);
}
}
And the SocialAuthenticationSuccessHandler class:
public class SocialAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
public static final String REDIRECT_PATH_BASE = "/#/login";
public static final String FIELD_TOKEN = "access_token";
public static final String FIELD_EXPIRATION_SECS = "expires_in";
private final Logger log = LoggerFactory.getLogger(getClass());
private final AuthorizationServerTokenServices authTokenServices;
private final String localClientId;
public SocialAuthenticationSuccessHandler(AuthorizationServerTokenServices authTokenServices, String localClientId){
this.authTokenServices = authTokenServices;
this.localClientId = localClientId;
}
#Override
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication authentication)
throws IOException, ServletException {
log.debug("Social user authenticated: " + authentication.getPrincipal() + ", generating and sending local auth");
OAuth2AccessToken oauth2Token = authTokenServices.createAccessToken(convertAuthentication(authentication)); //Automatically checks validity
String redirectUrl = new StringBuilder(REDIRECT_PATH_BASE)
.append("?").append(FIELD_TOKEN).append("=")
.append(encode(oauth2Token.getValue()))
.append("&").append(FIELD_EXPIRATION_SECS).append("=")
.append(oauth2Token.getExpiresIn())
.toString();
log.debug("Sending redirection to " + redirectUrl);
response.sendRedirect(redirectUrl);
}
private OAuth2Authentication convertAuthentication(Authentication authentication) {
OAuth2Request request = new OAuth2Request(null, localClientId, null, true, null,
null, null, null, null);
return new OAuth2Authentication(request,
//Other option: new UsernamePasswordAuthenticationToken(authentication.getPrincipal(), "N/A", authorities)
new PreAuthenticatedAuthenticationToken(authentication.getPrincipal(), "N/A")
);
}
private String encode(String in){
String res = in;
try {
res = UriUtils.encode(in, GeneralConstants.ENCODING_UTF8);
} catch(UnsupportedEncodingException e){
log.error("ERROR: unsupported encoding: " + GeneralConstants.ENCODING_UTF8, e);
}
return res;
}
}
This way your client app will receive your web app's access token via redirection to /#/login?access_token=my_access_token&expires_in=seconds_to_expiration, as long as you set the corresponding REDIRECT_PATH_BASE in SocialAuthenticationSuccessHandler.
I hope it helps.
First, I would strongly recommend you to move away from the password grant for such a use case.
Public clients (JavaScript, installed applications) cannot keep their client secret confidential, that's why they MUST NOT be assigned one : any visitor inspecting your JavaScript code can discover the secret, and thus implement the same authentication page you have, storing your users passwords in the process.
The implicit grant has been created exactly for what you are doing.
Using a redirection-based flow has the advantage of leaving the authentication mechanism up to the authorization server, instead of having each of your applications have a piece of it : that's mostly the definition of Single Sign On (SSO).
With that said, your question is tightly related to this one I just answered : Own Spring OAuth2 server together with 3rdparty OAuth providers
To sum up the answer :
In the end, it's about how your authorization server secures the AuthorizationEndpoint : /oauth/authorize. Since your authorization server works, you already have a configuration class extending WebSecurityConfigurerAdapter that handles the security for /oauth/authorize with formLogin. That's where you need to integrate social stuff.
You simply cannot use a password grant for what you're trying to achieve, you must have your public client redirect to the authorization server. The authorization server will then redirect to the social login as its security mechanism for the /oauth/authorize endpoint.
I was starting with the good answer of above (https://stackoverflow.com/a/33963286/3351474) however with my version of Spring Security (4.2.8.RELEASE) this fails. The reason is that in org.springframework.security.access.intercept.AbstractSecurityInterceptor#authenticateIfRequired the PreAuthenticatedAuthenticationToken of the answer is not authenticated. Some GrantedAuthorities have to be passed.
In addition sharing the token in an URL parameter is not good, it should always be hidden in an HTTPs payload or header. Instead a HTML template is loaded and the token value is inserted into a ${token} placeholder field.
Here the revised version:
NOTE: The used UserDetails here is implementing org.springframework.security.core.userdetails.UserDetails
#Component
public class SocialAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
#Autowired
private OAuth2TokenStore tokenStore;
#Qualifier("tokenServices")
#Autowired
private AuthorizationServerTokenServices authTokenServices;
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication authentication)
throws IOException, ServletException {
IClient user = ((SocialUserDetails) authentication.getPrincipal()).getUser();
// registration is not finished, forward the user, a marker interface
// IRegistration is used here, remove this if there no two step approach to
// create a user from a social network
if (user instanceof IRegistration) {
response.sendRedirect(subscriberRegistrationUrl + "/" + user.getId());
}
OAuth2AccessToken token = loginUser(user);
// load a HTML template from the class path and replace the token placeholder within, the HTML should contain a redirect to the actual page, but must store the token in a safe place, e.g. for preventing CSRF in the `sessionStorage` JavaScript storage.
String html = IOUtils.toString(getClass().getResourceAsStream("/html/socialLoginRedirect.html"));
html = html.replace("${token}", token.getValue());
response.getOutputStream().write(html.getBytes(StandardCharsets.UTF_8));
}
private OAuth2Authentication convertAuthentication(Authentication authentication) {
OAuth2Request request = new OAuth2Request(null, authentication.getName(),
authentication.getAuthorities(), true, null,
null, null, null, null);
// note here the passing of the authentication.getAuthorities()
return new OAuth2Authentication(request,
new PreAuthenticatedAuthenticationToken(authentication.getPrincipal(), "N/A", authentication.getAuthorities())
);
}
/**
* Logs in a user.
*/
public OAuth2AccessToken loginUser(IClient user) {
SecurityContext securityContext = SecurityContextHolder.getContext();
UserDetails userDetails = new UserDetails(user);
Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, "N/A", userDetails.getAuthorities());
securityContext.setAuthentication(authentication);
OAuth2Authentication oAuth2Authentication = convertAuthentication(authentication);
// delete the token because the client id in the DB is calculated as hash of the username and client id (here also also identical to username), this would be identical to the
// to an existing user. This existing one can come from a user registration or a previous user with the same name.
// If a new entity with a different ID is used the stored token hash would differ and the the wrong token would be retrieved
tokenStore.deleteTokensForUserId(user.getUsername());
OAuth2AccessToken oAuth2AccessToken = authTokenServices.createAccessToken(oAuth2Authentication);
// the DB id of the created user is returned as additional data, can be
// removed if not needed
((DefaultOAuth2AccessToken) oAuth2AccessToken).setAdditionalInformation(new HashMap<>());
oAuth2AccessToken.getAdditionalInformation().put("userId", user.getId());
return oAuth2AccessToken;
}
}
Example socialLoginRedirect.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Example App</title>
<meta http-equiv="Refresh" content="0; url=/index.html#/home"/>
</head>
<script>
window.sessionStorage.setItem('access_token', '${token}');
</script>
<body>
<p>Please follow this link.</p>
</body>
</html>
The configuration wiring in a WebSecurityConfigurerAdapter:
#Configuration
#EnableWebSecurity
#EnableWebMvc
#Import(WebServiceConfig.class)
public class AuthenticationConfig extends WebSecurityConfigurerAdapter {
#Value("${registrationUrl}")
private String registrationUrl;
#Autowired
private SocialAuthenticationSuccessHandler socialAuthenticationSuccessHandler;
#Value("${loginUrl}")
private String loginUrl;
#Override
protected void configure(HttpSecurity http) throws Exception {
List<String> permitAllUrls = new ArrayList<>();
// permit social log in
permitAllUrls.add("/auth/**");
http.authorizeRequests().antMatchers(permitAllUrls.toArray(new String[0])).permitAll();
SpringSocialConfigurer springSocialConfigurer = new SpringSocialConfigurer();
springSocialConfigurer.signupUrl(registrationUrl);
springSocialConfigurer.postFailureUrl(loginUrl);
springSocialConfigurer
.addObjectPostProcessor(new ObjectPostProcessor<SocialAuthenticationFilter>() {
#SuppressWarnings("unchecked")
public SocialAuthenticationFilter postProcess(SocialAuthenticationFilter filter){
filter.setAuthenticationSuccessHandler(socialAuthenticationSuccessHandler);
return filter;
}
});
http.apply(springSocialConfigurer);
http.logout().disable().csrf().disable();
http.requiresChannel().anyRequest().requiresSecure();
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
I implemented spring oauth2 to secure my rest services and additionally add social login and implicit signup for first time login . for user user you can generate the token using username and password only problem with generate the token for social user . for that you have to implement the Filter that will intercept your /oauth/token request before processing . here if you want to generate the the token for social user pass the username and facebook token , here you can use facebook token as password and generate the token for facebook user also . if facebook token updated then you have to write a db trigger also to update you token in user table .... may be it will help you

Resources