【问题标题】:Spring Auth2 generate custom Token from my servieSpring Oauth2 从我的服务生成自定义令牌
【发布时间】:2018-08-18 18:54:00
【问题描述】:

我已经实现了 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 实体一起发送?任何帮助将不胜感激。

【问题讨论】:

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


    【解决方案1】:

    您有 3 个选项。

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

    2. 您可以使用与您的 OAuth 流程匹配的 TokenGranter 实现之一。我只有客户端凭据流程的示例:

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

    【讨论】:

    猜你喜欢
    • 2013-09-25
    • 2015-05-16
    • 1970-01-01
    • 1970-01-01
    • 2015-08-26
    • 2017-04-25
    • 2014-06-15
    • 2020-06-30
    • 2019-10-23
    相关资源
    最近更新 更多