2016-11-04 108 views
0

我创建了一个自定义身份验证提供程序,我需要从该请求传递参数。Spring Security - Oauth2将请求参数传递给AuthenticationProvider

的enpoint是

/OAuth的/令牌?grant_type =密码&用户名= XXX &密码= XXX &的client_id = XXX & client_secret = XXX &国家=我

从以上请求我需要捕获country参数并将其传递给自定义身份验证提供程序,然后该身份验证提供程序将根据用户名,密码和国家/地区对用户进行身份验证。

上述请求通过ClientCredentialsTokenEndpointFilter过滤器,但是我无法将来自请求的国家/地区值设置到认证对象上。

<http pattern="/oauth/token" create-session="never" 
    authentication-manager-ref="clientAuthenticationManager" 
    xmlns="http://www.springframework.org/schema/security"> 
    <intercept-url pattern="/oauth/token" access="fullyAuthenticated" /> 
    <anonymous enabled="false" /> 
    <http-basic entry-point-ref="clientAuthenticationEntryPoint" />  
    <custom-filter ref="clientCredentialsTokenEndpointFilter" 
     after="BASIC_AUTH_FILTER" /> 
    <access-denied-handler ref="oauthAccessDeniedHandler" /> 
</http> 

请让我知道是否可以通过扩展任何安全功能来实现此目的。

我使用Spring 4.1Spring Security 4.0.3RELEASE

感谢, 安瓦尔

回答

0

你需要创建一个UsernamePasswordCountryAuthenticationToken

public class UsernamePasswordCountryAuthenticationToken extends UsernamePasswordAuthenticationToken { 

    private String country; 

    public UsernamePasswordCountryAuthenticationToken(Object principal, Object credentials, String country, Collection<? extends GrantedAuthority> authorities) { 
     super(principal, credentials, country, authorities); 
    } 

    public UsernamePasswordCountryAuthenticationToken(Object principal, Object credentials, String country) { 
     super(principal, credentials, country); 
    } 

    public String getCountry() { 
     return country; 
    } 
} 

,并覆盖ResourceOwnerPasswordTokenGranter

public class CustomResourceOwnerPasswordTokenGranter extends AbstractTokenGranter { 

    private static final String GRANT_TYPE = "password"; 

    private final AuthenticationManager authenticationManager; 

    public CustomResourceOwnerPasswordTokenGranter(AuthenticationManager authenticationManager, 
     AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService) { 
     super(tokenServices, clientDetailsService, GRANT_TYPE); 
     this.authenticationManager = authenticationManager; 
    } 


    protected OAuth2Authentication getOAuth2Authentication(AuthorizationRequest clientToken) { 
     Map<String, String> parameters = clientToken.getAuthorizationParameters(); 
     String username = parameters.get("username"); 
     String password = parameters.get("password"); 
     String country = parameters.get("country"); 

     Authentication userAuth = new UsernamePasswordCountryAuthenticationToken(username, password, country); 
     try { 
      userAuth = authenticationManager.authenticate(userAuth); 
     } catch (AccountStatusException ase) { 
      //covers expired, locked, disabled cases (mentioned in section 5.2, draft 31) 
      throw new InvalidGrantException(ase.getMessage()); 
     } catch (BadCredentialsException e) { 
      // If the username/password are wrong the spec says we should send 400/bad grant 
      throw new InvalidGrantException(e.getMessage()); 
     } 

     if (userAuth == null || !userAuth.isAuthenticated()) { 
      throw new InvalidGrantException("Could not authenticate user: " + username); 
     } 

     return new OAuth2Authentication(clientToken, userAuth); 
    } 
} 
在你的春季安全的OAuth配置文件

<bean id="customResourceOwnerPasswordTokenGranter" class="CustomResourceOwnerPasswordTokenGranter"> 
    <constructor-arg index="0" ref="authenticationManager"/> 
    <constructor-arg index="1" ref="tokenServices"/> 
    <constructor-arg index="2" ref="clientDetailsService"/> 
</bean> 

<oauth:authorization-server ...> 
    <oauth:custom-grant token-granter-ref="customResourceOwnerPasswordTokenGranter" /> 
</oauth:authorization-server> 

现在

最后,如果你已经正确配置AuthenticationManager有您的自定义AuthenticationProvider,你会接收UsernamePasswordCountryAuthenticationTokenAuthenticationProvider.authenticate method(Authentication auth)的实例,您可以在其中投射authUsernamePasswordCountryAuthenticationToken并且使用。

相关问题