Exact Finder
Exact Finder

Reputation: 73

Spring Auth2 generate custom Token from my servie

I have implemented Spring Security Auth2 with disabling password and its generating tokens and refresh tokens successfully.

My authorization server config is as follows

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    static final String CLIEN_ID = "clkey";
    static final String CLIENT_SECRET = "dsds876e67ds5s67ddfdf6dfdf767843";
    static final String GRANT_TYPE_PASSWORD = "password";
    static final String AUTHORIZATION_CODE = "authorization_code";
    static final String REFRESH_TOKEN = "refresh_token";
    static final String IMPLICIT = "implicit";
    static final String SCOPE_READ = "read";
    static final String SCOPE_WRITE = "write";
    static final String TRUST = "trust";
    static final int ACCESS_TOKEN_VALIDITY_SECONDS = 1*60*60;
    static final int FREFRESH_TOKEN_VALIDITY_SECONDS = 6*60*60;

    @Autowired
    private TokenStore tokenStore;

    @Autowired
    private UserApprovalHandler userApprovalHandler;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(ClientDetailsServiceConfigurer configurer) throws Exception {

        configurer
                .inMemory()
                .withClient(CLIEN_ID)
                .secret(CLIENT_SECRET)
                .authorizedGrantTypes(GRANT_TYPE_PASSWORD, AUTHORIZATION_CODE, REFRESH_TOKEN, IMPLICIT )
                .scopes(SCOPE_READ, SCOPE_WRITE, TRUST)
                .accessTokenValiditySeconds(ACCESS_TOKEN_VALIDITY_SECONDS).
                refreshTokenValiditySeconds(FREFRESH_TOKEN_VALIDITY_SECONDS);
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.tokenStore(tokenStore).userApprovalHandler(userApprovalHandler)
                .authenticationManager(authenticationManager);
    }
}

I disabled password auth by my custom auth provider

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider  {


    @Autowired
    private UserService auth2;

    @Autowired
    public CustomAuthenticationProvider(CoreUserService coreuserservice) {
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String password = ""; 
        String username = authentication.getName();

        if(!auth2.isUserExist(username)) {
            throw new BadCredentialsException("Authentication failed : bad credentials");
        }

        Authentication auth = new UsernamePasswordAuthenticationToken(username, password, auth2.grantAccess());
        return auth;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }

}

And i have a custom login service and if the login found ok i want to generate the same as in Memory token and get it as json value.

my service is as

public ResponseEntity<Map<String, Object>> dologin(String email,String password) throws UsernameNotFoundException {
    this.resetresponse();   
    this.responsedata.put("code", "200");
    User user = userdao.findByUsername(email);
    if(user == null)
        this.responsedata.put("code", "1"); //throw new UsernameNotFoundException("Invalid username or password.");     
    if(user != null && !encoder.matches(password, user.getPassword()))
        this.responsedata.put("code", "2"); //this.errors.add("2");
    if(! "200".equals(this.responsedata.get("code"))) {
        this.responsedata.put("status", "error");           
    }
    else {          

        org.springframework.security.core.userdetails.User coreuser = new org.springframework.security.core.userdetails.User(user.getEmail(), "$2a$10$56PJwERx23LPIEPv.gsouOhbn50b2T/AdMV553k0uIi1LflVgD9Y6", grantAccess());
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(coreuser.getUsername(), "", coreuser.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        //SecurityContextHolder.getContext().getAuthentication().getPrincipal();

        this.responsedata.put("status", "success");
        this.responsedata.put("data",user);
        this.responsedata.put("token",authenticationToken);         
    }
    return new ResponseEntity<Map<String, Object>>(this.responsedata,HttpStatus.OK);
} 

How can we generate token and refresh token and send it with the response json entity ? Any help would be much appreciated .

Upvotes: 0

Views: 2832

Answers (1)

Peter Borbas
Peter Borbas

Reputation: 178

You have 3 options.

  1. After you successfully authenticated your user with spring security, you send back a redirect to the /oauth/authorize url. From there Spring Security OAuth checks that the user is authenticated and will generate the token and act based on you selected OAuth2 flow.

  2. You can use one of the TokenGranter implementations that matches your OAuth flow. I only have example for the Client Credentials flow:

    @Service
    public class OauthService {
    
        @Autowired
        ClientCredentialsTokenGranter clientCredentialsTokenGranter;
    
        public String getAuthAccessToken() {
            Map<String, String> requestParameters = new HashMap<>();
            requestParameters.put("scope", "read");
            requestParameters.put("grant_type", OauthConst.GRANT_TYPE_CLIENT_CREDENTIALS);
            Set<String> scopes = Collections.singleton("read");
            TokenRequest tokenRequest = new TokenRequest(requestParameters, OauthConst.CLIENT_AUTH_ID, scopes,
                    OauthConst.GRANT_TYPE_CLIENT_CREDENTIALS);
            OAuth2AccessToken grant = clientCredentialsTokenGranter
                    .grant(OauthConst.GRANT_TYPE_CLIENT_CREDENTIALS, tokenRequest);
            return grant.getValue();
        }
    
    }
    
  3. You can get the token programatically of a previously authenticated user by @Autowire AuthorizationServerTokenServices which has a createAccessToken method. For this to work you need to have your user authenticated previously by OAuth so you can get an OAuth2Authentication for the method call from your security context.

Upvotes: 1

Related Questions