Spring Auth2从我的服务器生成自定义令牌

时间:2018-03-10 07:51:31

标签: java spring spring-security spring-security-oauth2

我已经实现了Spring Security Auth2,禁用了密码及其生成令牌并成功刷新令牌。

我的授权服务器配置如下

@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);
    }
}

我的自定义身份验证提供程序已禁用密码身份验证

@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);
    }

}

我有一个自定义登录服务,如果登录发现确定,我想生成与内存令牌相同的内容并将其作为json值。

我的服务是

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);
} 

我们如何生成令牌和刷新令牌并使用响应json实体发送它?任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

您有3个选项。

  1. 使用spring security成功验证用户身份后,您将重定向发送回/ oauth / authorize网址。从那里,Spring Security OAuth会检查用户是否已通过身份验证,并将生成令牌并根据您选择的OAuth2流程执行操作。

  2. 您可以使用与您的OAuth流匹配的TokenGranter个实现之一。我只有Client Credentials流程的示例:

    @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. 您可以通过具有@Autowire方法的AuthorizationServerTokenServices createAccessToken以编程方式获取以前经过身份验证的用户的令牌。为此,您需要先让OAuth对您的用户进行身份验证,以便从安全上下文中获取方法调用的OAuth2Authentication