- 引入相关包;
- 配置代码(SecurityConfig ,UserDetailsServiceImpl ,UserSecurity )
- 重点:
- config 配置
一定要在hasRole ("ADMIN")
前面,也就是说配置规则遵从从上往下的顺序authenticated
-
跳转之后不会进入后续拦截器,也就是说不会被security管理了。request.getRequestDispatcher(newUrl).forward(request, response)
- config 配置
- 代码参考
@EnableAutoConfiguration
@ComponentScan
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
/**
* 目前只供测试用例使用
* 模拟 UserDetailsService 验证,便于权限测试直接使用@WithUserDetails(@MockWidthUser需要指定用户名和密码)
*/
@Bean
public UserDetailsService userDetailsService() {
UserDetails userDetails = (UserDetails) new User("admin", "abc123456",
AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_ADMIN"));//授予 admin角色
return new InMemoryUserDetailsManager(Arrays.asList(userDetails));
}
/**
* 用户认证,主要是根据用户名获取用户角色、权限,来匹配用户登录和用户是否有权限操作
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
/**
* 访问权限过滤
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
// We recommend disabling CSRF protection completely only if you are creating a
// service that is used by non-browser clients
// 以此支持非浏览器 post 访问 shutdown
http.csrf().disable();
// 添加自定义过滤器,额外处理
http.addFilterBefore(new RouterFilter(), AnonymousAuthenticationFilter.class);
http.authorizeRequests()
.antMatchers("/assets/**", "/**/*.*", "/mocksession/**",
"/session/weixin", "/session/github").permitAll()
// 安全关闭服务接口,拥有 ADMIN 权限的用户可以访问该 rul
.antMatchers("/actuator/shutdown").hasRole("ADMIN")
.antMatchers("/app/redeploy").hasRole("ADMIN")
.anyRequest().authenticated() // 任何请求,登录后可以访问
.and()
.formLogin()
.loginPage("/")
.permitAll()
// 开启basic认证,若不添加此项,将不能通过curl的basic方式传递用户信息
.and()
.httpBasic()
.and()
// 重定向url由默认值/login?logout改为/
.logout()
.logoutSuccessUrl("/")
.permitAll()
.invalidateHttpSession(true);
}
}
UserDetailsServiceImpl 实现
@Component
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private UserService userService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserInfo userInfo = userService.getByLoginName(username);
if (userInfo == null) {
throw new UsernameNotFoundException(username + " 不存在!");
}
// 加密密码
String encode = passwordEncoder.encode(UserSecurity.getInternalPassword());
if (userInfo.isAdmin()) {
return new User(username, encode, AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_ADMIN"));
} else {
return new User(username, encode, AuthorityUtils.commaSeparatedStringToAuthorityList(""));
}
}
}
集成用户自定义登录session,转接到security,使用如下工具类
setUser
public class UserSecurity {
public static void setUser(UserInfo userInfo) {
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(userInfo.getLoginName(), getInternalPassword());
SecurityContextHolder.getContext().setAuthentication(authRequest);
}
public static String getInternalPassword() {
return "abc123456";
}
}