Java Spring security自定义身份验证提供程序总是导致错误的客户端凭据
我在spring security中实现了一个自定义身份验证提供程序,用于对用户进行身份验证。身份验证服务器位于远程端(Restful服务)。每次调用我的服务时,我都会遇到此错误(此代码到达Java Spring security自定义身份验证提供程序总是导致错误的客户端凭据,java,spring,authentication,spring-security,restful-authentication,Java,Spring,Authentication,Spring Security,Restful Authentication,我在spring security中实现了一个自定义身份验证提供程序,用于对用户进行身份验证。身份验证服务器位于远程端(Restful服务)。每次调用我的服务时,我都会遇到此错误(此代码到达 返回新的用户名PasswordAuthenticationToken(userDetails,authentication.getCredentials().toString(),grantedAuthority); part) 这是我的密码: CustomAuthenticationProvider 公共
返回新的用户名PasswordAuthenticationToken(userDetails,authentication.getCredentials().toString(),grantedAuthority);
part)
这是我的密码:
CustomAuthenticationProvider
公共类CustomAuthenticationProvider实现AuthenticationProvider{
@凌驾
公共身份验证(身份验证)引发AuthenticationException{
HttpComponents客户端HttpRequestFactory requestFactory=新的HttpComponents客户端HttpRequestFactory(HttpClients.createDefault());
RequestConfig RequestConfig=RequestConfig.custom().setConnectTimeout(60*1000)
.setSocketTimeout(60*1000).build();
PoolightPClientConnectionManager PoolightPClientConnectionManager=新的PoolightPClientConnectionManager(socketFactoryRegistry);
PoolighttpClientConnectionManager.setMaxTotal(20);
PoolighttpClientConnectionManager.setDefaultMaxPerRoute(20);
CloseableHttpClient httpClientBuilder=httpClientBuilder.create()
.setConnectionManager(PoolighttpClientConnectionManager).setDefaultRequestConfig(requestConfig)
.build();
setHttpClient(httpClientBuilder);
RestTemplate RestTemplate=新的RestTemplate(requestFactory);
UserInfoRequestBean UserInfoRequestBean=新的UserInfoRequestBean();
字符串用户名=(字符串)身份验证。getPrincipal();
setUsername(用户名);
setPassword((字符串)authentication.getCredentials());
HttpHeaders=新的HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity HttpEntity=新的HttpEntity(userInfoRequestBean,标头);
试试{
ResponseBean responseBody=restTemplate.exchange(getLoginUrl(),HttpMethod.POST,httpEntity,新参数化类型引用(){}).getBody();
UserDetails UserDetails=新的UserDetails();
setGender(responseBy.getResult().getGender());
setLastLoginDate(新日期());
setYaghutSessionId(responseBody.getResult().getSessionId());
setName(responseBy.getResult().getName());
userDetails.setUsername(用户名);
List GrantedAuthories=new ArrayList();
//向用户授予授权角色
添加(新的SimpleGrantedAuthority(“角色用户”);
返回新的UsernamePasswordAuthenticationToken(userDetails,authentication.getCredentials().toString(),GrantedAuthories);
}catch(RestClientException exp){
exp.printStackTrace();
//TODO:实现此方法
}
返回null;
}
@凌驾
公共布尔支持(类身份验证){
//TODO自动生成的方法存根
返回true;
}
私有字符串getLoginUrl(){
//返回restful服务url
}
}
Spring安全配置
在返回UsernamePasswordAuthenticationToken时,只需传递用户名,而不是传递UserDetails。以下是一个例子-
return new UsernamePasswordAuthenticationToken(username, authentication.getCredentials().toString(), grantedAuthorities);
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(HttpClients.createDefault());
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(60 * 1000)
.setSocketTimeout(60 * 1000).build();
PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
poolingHttpClientConnectionManager.setMaxTotal(20);
poolingHttpClientConnectionManager.setDefaultMaxPerRoute(20);
CloseableHttpClient httpClientBuilder = HttpClientBuilder.create()
.setConnectionManager(poolingHttpClientConnectionManager).setDefaultRequestConfig(requestConfig)
.build();
requestFactory.setHttpClient(httpClientBuilder);
RestTemplate restTemplate = new RestTemplate(requestFactory);
UserInfoRequestBean userInfoRequestBean = new UserInfoRequestBean();
String username = (String)authentication.getPrincipal();
userInfoRequestBean.setUsername(username);
userInfoRequestBean.setPassword((String)authentication.getCredentials());
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<?> httpEntity = new HttpEntity<UserInfoRequestBean>(userInfoRequestBean, headers);
try{
ResponseBean<LoginResponseBean> responseBody = restTemplate.exchange(getLoginUrl(), HttpMethod.POST, httpEntity, new ParameterizedTypeReference<ResponseBean<LoginResponseBean>>() {}).getBody();
UserDetails userDetails = new UserDetails();
userDetails.setGender(responseBody.getResult().getGender());
userDetails.setLastLoginDate(new Date());
userDetails.setYaghutSessionId(responseBody.getResult().getSessionId());
userDetails.setName(responseBody.getResult().getName());
userDetails.setUsername(username);
List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
// Granting authorization roles to user
grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_USER"));
return new UsernamePasswordAuthenticationToken(userDetails, authentication.getCredentials().toString(), grantedAuthorities);
}catch (RestClientException exp) {
exp.printStackTrace();
//TODO: implement this method
}
return null;
}
@Override
public boolean supports(Class<?> authentication) {
// TODO Auto-generated method stub
return true;
}
private String getLoginUrl(){
//return restful service url
}
}
<bean id="oauthAccessDeniedHandler" class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />
<bean id="clientCredentialsTokenEndpointFilter"
class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="customAuthenticationManager" />
</bean>
<bean id="clientAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="test/client" />
<property name="typeName" value="Basic" />
</bean>
<bean id="customProvider"
class="com.adpdigital.idm.security.provider.CustomAuthenticationProvider" />
<authentication-manager id="customAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<authentication-provider ref="customProvider" />
</authentication-manager>
<http pattern="/oauth/token" create-session="stateless" authentication-manager-ref="customAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY"/>
<anonymous enabled="false"/>
<http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<!-- include this only if you need to authenticate clients via request parameters -->
<custom-filter ref="clientCredentialsTokenEndpointFilter" after="BASIC_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
return new UsernamePasswordAuthenticationToken(username, authentication.getCredentials().toString(), grantedAuthorities);