Reputation: 73
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
Reputation: 178
You have 3 options.
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.
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();
}
}
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