java - 带有 OAuth2 和自定义身份验证提供程序的 Spring Boot REST 服务
问题描述
我正在基于spring greeting 示例构建一个 REST 服务。这很好用,我很高兴春天为我节省了时间。今天我试图通过访问令牌和刷新令牌来获得 OAuth2 安全性。当我使用将用户名和密码存储在自己的存储库中的示例时,这很好用。问题是我需要一个自定义身份验证提供程序,因为我需要对第三方系统进行身份验证,该系统将返回 true 或 false 提供用户名和密码。
我确实找到了自定义安全提供程序的示例,但没有使用 AuthorizationServer、ResourceServer、SecurityServer 和自定义授权服务器的从梯度到严重的示例……有人有或可以提供这样的示例吗?
我没有结合所有的例子,因为它们都略有不同......
在此先感谢您的帮助!
问候,
彼得
解决方案
@Configuration
@EnableAuthorizationServer
public class OAuth2Configuration extends AuthorizationServerConfigurerAdapter{
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private UserDetailsService userDetailsService;
@Bean
public WebResponseExceptionTranslator loggingExceptionTranslator() {
return new DefaultWebResponseExceptionTranslator() {
@Override
public ResponseEntity<OAuth2Exception> translate(Exception e) throws Exception {
// This is the line that prints the stack trace to the log. You can customise this to format the trace etc if you like
e.printStackTrace();
// Carry on handling the exception
ResponseEntity<OAuth2Exception> responseEntity = super.translate(e);
HttpHeaders headers = new HttpHeaders();
headers.setAll(responseEntity.getHeaders().toSingleValueMap());
OAuth2Exception excBody = responseEntity.getBody();
return new ResponseEntity<>(excBody, headers, responseEntity.getStatusCode());
}
};
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory().withClient("webapp")
.secret("{bcrypt}$2a$10$kwz.jnLVLwJOYTAp2r/oG.8tfAN/EC5dK1w5beLgfpuFT6Puprgq.")
.authorizedGrantTypes("implicit", "password", "authorization_code", "refresh_toke")
.scopes("read", "write").accessTokenValiditySeconds(3600 * 8).refreshTokenValiditySeconds(3600 * 8);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer configurer) throws Exception {
configurer.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()");
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
enhancerChain.setTokenEnhancers(Arrays.asList(tokenEnhancer(), jwtAccessTokenConverter()));
endpoints
.authenticationManager(this.authenticationManager)
.accessTokenConverter(jwtAccessTokenConverter())
.tokenEnhancer(enhancerChain)
.userDetailsService(userDetailsService)
.exceptionTranslator(loggingExceptionTranslator());
}
@Bean
public TokenEnhancer tokenEnhancer() {
return (accessToken, authentication) -> {
MyPrincipal userDetails = (MyPrincipal)userDetailsService.loadUserByUsername(authentication.getName());
Map<String, Object> additionalInfor = new HashMap<>();
additionalInfor.put("accountName", userDetails.getUsername());
additionalInfor.put("authorities", userDetails.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList()));
((DefaultOAuth2AccessToken)accessToken).setAdditionalInformation(additionalInfor);
return accessToken;
};
}
@Bean
UserAuthenticationConverter userAuthenticationConverter() {
DefaultUserAuthenticationConverter converter = new DefaultUserAuthenticationConverter();
converter.setUserDetailsService(userDetailsService);
return converter;
}
@Bean
AccessTokenConverter accessTokenConverter() {
DefaultAccessTokenConverter converter = new DefaultAccessTokenConverter();
converter.setUserTokenConverter(userAuthenticationConverter());
return converter;
}
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setAccessTokenConverter(accessTokenConverter());
converter.setSigningKey("123");
return converter;
}
@Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowCredentials(true);
configuration.addAllowedOrigin("*");
configuration.addAllowedHeader("*");
configuration.addAllowedMethod("*");
source.registerCorsConfiguration("/**", configuration);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return bean;
}
}
推荐阅读
- nativescript - Nativescript UI 未更新
- scala - 在像 scala 这样的函数式编程语言中,停止迭代集合的方法是什么?例如; 如果给定包含 0,则返回 true
- python - 如何在 Flask SQLAlchemy 中递归获取孩子?
- sql - 带有名称和 empID 的 Oracle Case 语句
- java - 在Java中打印小数点后1位
- eclipse - 如何判断eclipse项目的成熟度
- ios - MacOS - iOS 模拟器:如何禁用模拟器上的新工具栏?[包含图片]
- visual-studio-code - 出现错误 - ASL CLI 不起作用 - 未知选项“-l”
- ios - 如何设置 UICollectionViewCell 的内容
- python - 使用Paramiko实现跳转主机(端口转发)所涉及的主机/IP地址和端口说明