资源服务器相关说明:https://blog.csdn.net/zhuwei_clark/article/details/103980661
扩展登录方式:https://blog.csdn.net/zhuwei_clark/article/details/103980279
自定义退出:https://blog.csdn.net/zhuwei_clark/article/details/103979939
自定义登录退出:https://blog.csdn.net/zhuwei_clark/article/details/103979919
限制登录人数:https://blog.csdn.net/zhuwei_clark/article/details/103979980
上面是相关的文章,上面讲解过的,这里就不在重复讲了,只讲主要的内容了
项目结构如下:
config中未redis配置,没什么好说的主要是实现了序列。
filter,handler,provider,token,service,auth主要是为了实现扩展登录方式,详细的说明看下上面的文章链接。
重点说下AuthServer的配置:
扫描二维码关注公众号,回复:
8609635 查看本文章
/**
* 认证服务配置
* @author 大仙
*/
@Configuration
@EnableConfigurationProperties(KeyProperties.class)
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private ApplicationContext applicationContext;
@Autowired
private TokenStore authTokenStore;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private UsernameUserDetailService userDetailService;
@Autowired
private DataSource dataSource;
@Bean("jdbcClientDetailsService")
public ClientDetailsService clientDetailsService(){
return new JdbcClientDetailsService(dataSource);
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
// 使用JdbcClientDetailsService客户端详情服务
clients.withClientDetails(clientDetailsService());
}
@Bean("authTokenStore")
//指定filter用服务端的
@Primary
public TokenStore authTokenStore() {
return new JwtTokenStore(authJwtAccessTokenConverter());
}
/**
* 配置授权服务器端点,如令牌存储,令牌自定义,用户批准和授权类型,不包括端点安全配置
* @param endpoints
* @throws Exception
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
endpoints
.authenticationManager(authenticationManager)
.userDetailsService(userDetailService)
.tokenServices(defaultTokenServices());
}
@Primary
@Bean
public DefaultTokenServices defaultTokenServices() {
Collection<TokenEnhancer> tokenEnhancers = applicationContext.getBeansOfType(TokenEnhancer.class).values();
TokenEnhancerChain tokenEnhancerChain=new TokenEnhancerChain();
tokenEnhancerChain.setTokenEnhancers(new ArrayList<>(tokenEnhancers));
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(authTokenStore);
//是否可以重用刷新令牌
defaultTokenServices.setReuseRefreshToken(false);
defaultTokenServices.setSupportRefreshToken(true);
defaultTokenServices.setAccessTokenValiditySeconds(Constant.AUTH_EXP_TIME);
defaultTokenServices.setRefreshTokenValiditySeconds(Constant.REFRESH_AUTH_EXP_TIME);
defaultTokenServices.setTokenEnhancer(tokenEnhancerChain);
return defaultTokenServices;
}
/**
* 配置授权服务器端点的安全
* @param oauthServer
* @throws Exception
*/
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) {
oauthServer
.tokenKeyAccess("permitAll()")
.checkTokenAccess("permitAll()")
.allowFormAuthenticationForClients();
}
@Bean("jwtAccessTokenConverter")
public JwtAccessTokenConverter authJwtAccessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessToken();
KeyPair keyPair = new KeyStoreKeyFactory(new ClassPathResource("kevin_key.jks"), "wecodeCloud".toCharArray())
.getKeyPair("wecode");
converter.setKeyPair(keyPair);
return converter;
}
}
WebSucrityConfig配置
@Configuration
@EnableWebSecurity
@Order(1)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 用户详情业务实现
*/
@Autowired
private UsernameUserDetailService userDetailsService;
@Autowired
private PhoneUserDetailService phoneUserDetailService;
@Autowired
private QrUserDetailService qrUserDetailService;
@Autowired
private OpenIdUserDetailService openIdUserDetailService;
/**
* 重新实例化bean
*/
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// 由于使用的是JWT,我们这里不需要csrf
http.cors().
and().csrf().disable()
.authorizeRequests().requestMatchers(CorsUtils::isPreFlightRequest).permitAll().and()
.logout().addLogoutHandler(getLogoutHandler()).logoutSuccessHandler(getLogoutSuccessHandler()).and()
.addFilterBefore(getPhoneLoginAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(getQrLoginAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(getUsernameLoginAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(getOpenIdLoginAuthenticationFilter(),UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(getCodeLoginAuthenticationFilter(),UsernamePasswordAuthenticationFilter.class)
.authorizeRequests().antMatchers("/oauth/**").permitAll().and()
.authorizeRequests().antMatchers("/logout/**").permitAll().and()
.authorizeRequests().antMatchers("/js/**","/favicon.ico").permitAll().and()
.authorizeRequests().antMatchers("/v2/api-docs/**","/webjars/**","/swagger-resources/**","/*.html").permitAll().and()
// 其余所有请求全部需要鉴权认证
.authorizeRequests().anyRequest().authenticated()
;
}
/**
* 用户验证
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(phoneAuthenticationProvider());
auth.authenticationProvider(daoAuthenticationProvider());
auth.authenticationProvider(openIdAuthenticationProvider());
auth.authenticationProvider(qrAuthenticationProvider());
}
@Bean
public DaoAuthenticationProvider daoAuthenticationProvider(){
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
// 设置userDetailsService
provider.setUserDetailsService(userDetailsService);
// 禁止隐藏用户未找到异常
provider.setHideUserNotFoundExceptions(false);
// 使用BCrypt进行密码的hash
provider.setPasswordEncoder(passwordEncoder());
return provider;
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public PhoneAuthenticationProvider phoneAuthenticationProvider(){
PhoneAuthenticationProvider provider = new PhoneAuthenticationProvider();
// 设置userDetailsService
provider.setUserDetailsService(phoneUserDetailService);
// 禁止隐藏用户未找到异常
provider.setHideUserNotFoundExceptions(false);
return provider;
}
@Bean
public QrAuthenticationProvider qrAuthenticationProvider(){
QrAuthenticationProvider provider = new QrAuthenticationProvider();
// 设置userDetailsService
provider.setUserDetailsService(qrUserDetailService);
// 禁止隐藏用户未找到异常
provider.setHideUserNotFoundExceptions(false);
return provider;
}
@Bean
public OpenIdAuthenticationProvider openIdAuthenticationProvider(){
OpenIdAuthenticationProvider provider = new OpenIdAuthenticationProvider();
// 设置userDetailsService
provider.setUserDetailsService(openIdUserDetailService);
// 禁止隐藏用户未找到异常
provider.setHideUserNotFoundExceptions(false);
return provider;
}
/**
* 账号密码登录
* @return
*/
@Bean
public UsernamePasswordAuthenticationFilter getUsernameLoginAuthenticationFilter(){
UsernamePasswordAuthenticationFilter filter = new UsernamePasswordAuthenticationFilter();
try {
filter.setAuthenticationManager(this.authenticationManagerBean());
} catch (Exception e) {
e.printStackTrace();
}
filter.setAuthenticationSuccessHandler(getLoginSuccessAuth());
filter.setAuthenticationFailureHandler(getLoginFailure());
return filter;
}
/**
* 手机验证码登陆过滤器
* @return
*/
@Bean
public PhoneLoginAuthenticationFilter getPhoneLoginAuthenticationFilter() {
PhoneLoginAuthenticationFilter filter = new PhoneLoginAuthenticationFilter();
try {
filter.setAuthenticationManager(this.authenticationManagerBean());
} catch (Exception e) {
e.printStackTrace();
}
filter.setAuthenticationSuccessHandler(getLoginSuccessAuth());
filter.setAuthenticationFailureHandler(getLoginFailure());
return filter;
}
/**
* 二维码登录过滤器
* @return
*/
@Bean
public QrLoginAuthenticationFilter getQrLoginAuthenticationFilter() {
QrLoginAuthenticationFilter filter = new QrLoginAuthenticationFilter();
try {
filter.setAuthenticationManager(this.authenticationManagerBean());
} catch (Exception e) {
e.printStackTrace();
}
filter.setAuthenticationSuccessHandler(getLoginSuccessAuth());
filter.setAuthenticationFailureHandler(getLoginFailure());
return filter;
}
/**
* 微信OPENID登录
* @return
*/
@Bean
public OpenIdLoginAuthenticationFilter getOpenIdLoginAuthenticationFilter() {
OpenIdLoginAuthenticationFilter filter = new OpenIdLoginAuthenticationFilter();
try {
filter.setAuthenticationManager(this.authenticationManagerBean());
} catch (Exception e) {
e.printStackTrace();
}
filter.setAuthenticationSuccessHandler(getLoginSuccessAuth());
filter.setAuthenticationFailureHandler(getLoginFailure());
return filter;
}
/**
* code登录
* @return
*/
@Bean
public CodeLoginAuthenticationFilter getCodeLoginAuthenticationFilter() {
CodeLoginAuthenticationFilter filter = new CodeLoginAuthenticationFilter();
try {
filter.setAuthenticationManager(this.authenticationManagerBean());
} catch (Exception e) {
e.printStackTrace();
}
filter.setAuthenticationSuccessHandler(getLoginSuccessAuth());
filter.setAuthenticationFailureHandler(getLoginFailure());
return filter;
}
@Bean
public MyLoginAuthSuccessHandler getLoginSuccessAuth(){
MyLoginAuthSuccessHandler myLoginAuthSuccessHandler = new MyLoginAuthSuccessHandler();
return myLoginAuthSuccessHandler;
}
@Bean
public MyLoginFailureHandler getLoginFailure(){
MyLoginFailureHandler myLoginFailureHandler = new MyLoginFailureHandler();
return myLoginFailureHandler;
}
@Bean
public LogoutHandler getLogoutHandler(){
MyLogoutHandler myLogoutHandler = new MyLogoutHandler();
return myLogoutHandler;
}
@Bean
public LogoutSuccessHandler getLogoutSuccessHandler(){
MyLogoutSuccessHandler logoutSuccessHandler = new MyLogoutSuccessHandler();
return logoutSuccessHandler;
}
}