我创建了一个自定义身份验证提供程序,我需要从请求中传递参数。
要点是
/的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.1
和Spring Security 4.0.3RELEASE
谢谢, 安华
答案 0 :(得分: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);
}
}
最后在Spring Security 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
,那么您将收到UsernamePasswordCountryAuthenticationToken
到AuthenticationProvider.authenticate method(Authentication auth)
的实例,您可以在其中{{1}转到auth
并使用。