User defined OAuth2.0 token issuing interface address

Login implementation

Take the example of a web browser login:

The essence of web login based on OAuth2.0-password mode is that the browser passes the user name and password to the background through the / oauth/token interface, and then returns a valid token to the browser after the background verification

Send the request through the curl command

  • The request header Authorization stores the results of clientId and secret encoded by Base64

  • The request parameters include user name, password and grant_type).

curl --location --request 
POST 'http://localhost:8101/oauth/token?username=zhangsan&password=123456&grant_type=password \
--header 'Authorization: Basic bmltbzE6MTIzNDU2'

Response content

{
  "scope": "[all, read, write]",
  "code": 0,
  "access_token": "7e1d19dd-5cef-4993-a1c3-c35aa53d9b29",
  "token_type": "bearer",
  "refresh_token": "992518eb-4357-4283-8673-a9ca96ad2a9e",
  "expires_in": 7199
}

problem

What if we want to name the login interface / login?

Method 1

Configure a pathMapping in the authorization server configureradapter to override the original path

@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
	@Override
	public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
		endpoints
				.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST)
				.pathMapping("/oauth/token","/login");	}
}

Method 2

According to the above Source code analysis Spring Security OAuth2 generation token execution process To implement the core logic of tokenendpoint ා postaccesstoken() method, and redefine a / login interface

Review one of the images above:

The core code is as follows:


@PostMapping(value = "/login")
@ResponseBody
public String doLogin(
            HttpServletRequest request, 
            String username, 
            String password) {
        
    // Custom response object
    LoginRes res = new LoginRes();
      
    try {
       // The request header is base64 decoded to obtain the client id and client secret
       String[] tokens = CryptUtils.decodeBasicHeader(request.getHeader("Authorization"));
       String clientId = tokens[0];
       String clientSecret = tokens[1];
            
       // Get client details through clientId
       ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId);
            
       // Verify client details 
       if (clientDetails == null) {
          throw new UnapprovedClientAuthenticationException("Unknown client id : " + clientId);
       }
       
       if (!passwordEncoder.matches(clientSecret, clientDetails.getClientSecret())) {
          throw new UnapprovedClientAuthenticationException("Invalid client secret for client id : " + clientId);
       }

       // Build an Authentication object by using username and password
       UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(req.getUsername(),
                    req.getPassword());
                    
        // Verify user information
        Authentication auth = authenticationManager.authenticate(authRequest);
        // Context put into security
       SecurityContextHolder.getContext().setAuthentication(auth);

       // Get a TokenRequest object through Client information and request parameters
      TokenRequest tokenRequest = new TokenRequest(new HashMap<String, String>(), clientId,
                    clientDetails.getScope(), "password");
            
      // Building OAuthRequest through TokenRequest and ClientDetails 
      OAuth2Request oAuth2Request = tokenRequest.createOAuth2Request(clientDetails);
            
      // Building OAuth2Authentication through OAuth2Request and Authentication 
      OAuth2Authentication oAuth2Authentication = new OAuth2Authentication(oAuth2Request, auth);
            
      // Building OAuth2AccessToken through OAuth2Authentication
      OAuth2AccessToken token = authorizationServerTokenServices.createAccessToken(oAuth2Authentication);
            
      // Encapsulate token information into a custom response object
       res.setAccessToken(token.getValue());
       res.setTokenType(token.getTokenType());
       res.setRefreshToken(token.getRefreshToken().getValue());
      res.setExpiresIn(token.getExpiresIn());
      res.setScope(token.getScope().toString());

  } catch (Exception e) {
      log.warn("Fail to login of user {} for {}", req.getUsername(), e.getMessage());
        }
   return JsonUtil.toJsonString(res);
 }

Tags: Programming curl Spring

Posted on Tue, 30 Jun 2020 01:32:05 -0400 by limpo