权限管理的曲折历程,血泪史。可以拦截器实现,也可以spring security。最终解决spring security页面出现重定向问题。
拦截器和过滤器区别,面试高频点了。
- 拦截器(Interceptor)、 过滤器(filter)
拦截器(Interceptor)是spring的,实现很简单。
- 拦截器代码
public class LoginHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Object user = request.getSession().getAttribute("user");
if (user == null){
request.setAttribute("message","没有权限,请先登录");
request.getRequestDispatcher("/").forward(request,response);//转发
return false;
}else {
return true;
}
}
}
- 配置拦截器,拦截路径。
@Configuration
public class LoginConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginHandlerInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/","/login","/user/login","/images/**","/js/**","/styles/**");
registry.addInterceptor(new AdminHandlerInterceptor())
.addPathPatterns("/account/**","/admin/**","/cost/**","/role/**","/service/**");
}
}
上面就实现类简单的登录拦截和权限拦截。当然还尝试了 spring security。遇到最大的问题就是重定向。
这里重定向的原因是:ajax请求。不知道有没有解决方案。
- 表单提交绝对是可以的,这里的登陆验证和登出都不用经过controller,由 spring security完成。注意请求路径。
授权
这儿还有一个🕳:.hasRole("ADMIN"),数据库必须有前缀ROLE_
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Resource
private UserDetailsService userDetailsService;
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
// 认证用户的来源(数据库)
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
//配置springsecurity相关信息
protected void configure(HttpSecurity http) throws Exception {
// 释放静态资源,指定资源拦截规则,指定自定义认证页面,指定退出认证配置,csrf配置
http.authorizeRequests()
.antMatchers("/","/toLogin", "/js/**", "/images/**", "/plugin/**", "/styles/**")
.permitAll()
.antMatchers("/account/**","/admin/**","/cost/**","/role/**","/service/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/toLogin")
.loginProcessingUrl("/login")
.defaultSuccessUrl("/main/index")
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/toLogin")
.invalidateHttpSession(true)
.permitAll()
//禁用csrf,建议不禁用,登录和登出必须携带token
.and()
.csrf()
.disable();
}
}
- 建议不禁用,登录和登出必须携带token,页面代码
数据库认证
@Service
public class MyUserDetailService implements UserDetailsService {
@Resource
private UserMapper mapper;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
User user = mapper.selectByTelephone(s);
if (user == null){
throw new UsernameNotFoundException("不存在");
}
System.out.println(user);
List<GrantedAuthority> authorities = AuthorityUtils.commaSeparatedStringToAuthorityList(user.getRole());
return new org.springframework.security.core.userdetails.User(user.getUserName(),new BCryptPasswordEncoder().encode(user.getUserPwd()),authorities);
}
}
最后没用spring security,还是不太了解,和自己已经实现的东西不太好结合。这个还是要事先考虑好。
每天一个小技巧
作 者:凑数的园丁
出 处:https://www.cnblogs.com/lq-404/
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。