优化security 登录

This commit is contained in:
maxf 2018-11-21 11:31:15 +08:00
parent 535b47bc9e
commit df5204bc10
7 changed files with 102 additions and 28 deletions

View File

@ -5,7 +5,7 @@
<groupId>com.yexuejc.springboot</groupId>
<artifactId>yexuejc-springboot-parent</artifactId>
<version>1.1.5</version>
<version>1.1.6</version>
<packaging>pom</packaging>
<name>${project.artifactId}</name>

View File

@ -9,7 +9,7 @@
<parent>
<groupId>com.yexuejc.springboot</groupId>
<artifactId>yexuejc-springboot-parent</artifactId>
<version>1.1.5</version>
<version>1.1.6</version>
<!-- 本地打包:使用相对关联路径 -->
<!--<relativePath>../../yexuejc</relativePath>-->
</parent>

View File

@ -0,0 +1,24 @@
package com.yexuejc.springboot.base.exception;
/**
* 类型转换异常
*
* @author: maxf
* @date: 2018/5/12 18:36
*/
public class ClassConvertExeption extends RuntimeException {
private static final long serialVersionUID = -2390195902982826130L;
/**
* 错误码
*/
private String code = "E";
public ClassConvertExeption() {
super("类型转换异常");
}
public ClassConvertExeption(String message) {
super(message);
}
}

View File

@ -1,12 +1,10 @@
package com.yexuejc.springboot.base.security;
import com.yexuejc.springboot.base.autoconfigure.MutiRedisAutoConfiguration;
import com.yexuejc.springboot.base.security.inte.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.config.BeanIds;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
@ -17,6 +15,7 @@ import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.context.SecurityContextRepository;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
@ -39,10 +38,6 @@ public abstract class SecurityConfig extends WebSecurityConfigurerAdapter {
return super.authenticationManagerBean();
}
@Autowired
@Qualifier(MutiRedisAutoConfiguration.BEAN_REDIS_TEMPLATE0)
private RedisTemplate<Object, Object> redisTemplate0;
@Bean
public static NoOpPasswordEncoder passwordEncoder() {
@ -58,11 +53,31 @@ public abstract class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
UserDetailsService userDetailsService = new UserDetailsManager(getUserService());
auth.authenticationProvider(new ConsumerAuthenticationProvider(userDetailsService, getUserService()));
UserDetailsService userDetailsService = createUserDetailsManager();
AuthenticationProvider authenticationProvider = createConsumerAuthenticationProvider(userDetailsService);
auth.authenticationProvider(authenticationProvider);
auth.userDetailsService(userDetailsService);
}
/**
* 初始化 AuthenticationProvider
*
* @param userDetailsService
* @return
*/
protected AuthenticationProvider createConsumerAuthenticationProvider(UserDetailsService userDetailsService) {
return new ConsumerAuthenticationProvider(userDetailsService, getUserService());
}
/**
* 初始化 UserDetailsService
*
* @return
*/
protected UserDetailsService createUserDetailsManager() {
return new UserDetailsManager(getUserService());
}
@Bean
public ConsumerAuthenticationProcessingFilter consumerAuthenticationProcessingFilter(
@ -134,7 +149,7 @@ public abstract class SecurityConfig extends WebSecurityConfigurerAdapter {
.cors()
.and().servletApi().disable()
.requestCache().disable()
.securityContext().securityContextRepository(new ConsumerSecurityContextRepository(redisTemplate0))
.securityContext().securityContextRepository(createConsumerSecurityContextRepository())
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
@ -142,6 +157,22 @@ public abstract class SecurityConfig extends WebSecurityConfigurerAdapter {
UsernamePasswordAuthenticationFilter.class);
}
/**
* 创建 SecurityContextRepository
*
* @return
*/
protected SecurityContextRepository createConsumerSecurityContextRepository() {
return new ConsumerSecurityContextRepository(getRedisDB());
}
/**
* 初始化放置用户信息的reids库
*
* @return
*/
protected abstract RedisTemplate<Object, Object> getRedisDB();
@Override
public void configure(WebSecurity web) throws Exception {

View File

@ -1,6 +1,7 @@
package com.yexuejc.springboot.base.security;
import com.yexuejc.base.util.StrUtil;
import com.yexuejc.springboot.base.exception.ClassConvertExeption;
import com.yexuejc.springboot.base.exception.UserNotAuthoriayException;
import com.yexuejc.springboot.base.security.inte.User;
import com.yexuejc.springboot.base.security.inte.UserService;
@ -31,22 +32,34 @@ public class UserDetailsManager extends InMemoryUserDetailsManager {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User consumer = userService.getConsumerByUserName(username);
if (StrUtil.isEmpty(consumer)) {
throw new UsernameNotFoundException(username);
return loadUser(username);
}
protected ConsumerUser loadUser(String username) {
Object user = userService.getConsumerByUserName(username);
if (user instanceof User) {
User consumer = (User) user;
if (StrUtil.isEmpty(consumer)) {
throw new UsernameNotFoundException(username);
}
// 处理用户权限
List<GrantedAuthority> authorities = new ArrayList<>();
if (StrUtil.isEmpty(consumer.getRoles())) {
throw new UserNotAuthoriayException("用户" + username + "缺少权限");
}
for (String role : consumer.getRoles()) {
authorities.add(new SimpleGrantedAuthority(role));
}
ConsumerUser consumerUser = new ConsumerUser(consumer.getMobile(), consumer.getPwd(),
consumer.getEnable(), consumer.getNonExpire(), true, consumer.getNonLock(),
authorities, consumer.getConsumerId(), null, System.currentTimeMillis());
return consumerUser;
} else if (user instanceof ConsumerUser) {
return (ConsumerUser) user;
} else {
throw new ClassConvertExeption("获取登录用户信息返回结果类型必须是com.yexuejc.springboot.base.security.inte.User实现类" +
"或者com.yexuejc.springboot.base.security.ConsumerUser继承类");
}
// 处理用户权限
List<GrantedAuthority> authorities = new ArrayList<>();
if (StrUtil.isEmpty(consumer.getRoles())) {
throw new UserNotAuthoriayException("用户" + username + "缺少权限");
}
for (String role : consumer.getRoles()) {
authorities.add(new SimpleGrantedAuthority(role));
}
ConsumerUser consumerUser = new ConsumerUser(consumer.getMobile(), consumer.getPwd(),
consumer.getEnable(), consumer.getNonExpire(), true, consumer.getNonLock(),
authorities, consumer.getConsumerId(), null, System.currentTimeMillis());
return consumerUser;
}
}

View File

@ -18,7 +18,7 @@ public interface UserService {
* @param username 登录账号
* @return
*/
User getConsumerByUserName(String username);
Object getConsumerByUserName(String username);
/**
* 校验短信验证码=>短信登录

View File

@ -47,6 +47,11 @@ public class MySecurityConfig extends SecurityConfig {
@Qualifier(MutiRedisAutoConfiguration.BEAN_REDIS_TEMPLATE0)
private RedisTemplate<Object, Object> redisTemplate0;
@Override
protected RedisTemplate<Object, Object> getRedisDB() {
return redisTemplate0;
}
/**
* 保存登录信息至redis
*
@ -184,4 +189,5 @@ public class MySecurityConfig extends SecurityConfig {
response.getWriter().close();
});
}
}