最近在用boot+Security+framework写权限,感觉写起来挺简单的,今天就写下次博客希望能帮助到哪些有需要的人:
**注:在使使用前需要编写两个方法:
一个根据用户名查找对应的权限(本文该方法名为getInfoByUsername)
一个是根据用户名查找用户 (本文该方法名为getByUsername)
1.引入Security+freemarker依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2.1-b03</version>
</dependency>
2.依赖引入后到spring-security-taglibs包中META-INF下security.tld复制出来,放到/resources/static下,最后建一个目录tags,如下:
3.编写Security+freemarker整合的配置类
public class TldConfig extends WebMvcConfigurerAdapter {
@Resource
private FreeMarkerConfigurer configurer;
@PostConstruct
public void freeMarkerConfigurer() {
List<String> tlds = new ArrayList<String>();
tlds.add("/static/tags/security.tld");
TaglibFactory taglibFactory = configurer.getTaglibFactory();
taglibFactory.setClasspathTlds(tlds);
if (taglibFactory.getObjectWrapper() == null) {
taglibFactory.setObjectWrapper(configurer.getConfiguration().getObjectWrapper());
}
}
}
4.编写Security的额外配置类
/**
* Security 配置类
*/
@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//拦截器用来拦截用户登陆的请求获取用户信息
@Autowired
private UserInfoFilter userInfoFilter;
@Resource
private UserDetailsService userDetailsService;
@Bean
public PasswordEncoder getEncoder() {
return new BCryptPasswordEncoder();
}
/**
* 用户签名,验证用户密码是否正确,密码编码器
*
* @param auth 用户签名管理器,使用userDetails的方式来完成用户签名
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService)
.passwordEncoder(getEncoder());
}
/**
* 不拦截所有静态方法
*
* @param web
* @throws Exception
*/
@Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/**.js", "/css/**", "/images/**", "/font/**", "/lay/**");
}
/**
* Security自定义签名
*
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()//所有验证后的请求
.anyRequest().authenticated()//必须验证后才能访问
.and()
.formLogin()//添加登录页面
.loginPage("/login.html")//表单登录页面地址
.defaultSuccessUrl("/")//登录成功后跳转的页面
.permitAll()//所有人都可以访问
.and()
.logout()//增加退出
.logoutSuccessUrl("/logout.html")//退出成功后去往的页面
.permitAll()//所有人都可以操作
.and()
.rememberMe().tokenValiditySeconds(86400)//记住我功能
.key("remember-token")//记住我的名称
.and()
.csrf().disable()
.addFilterAfter(userInfoFilter, UsernamePasswordAuthenticationFilter.class);
}
}
4.编写拦截请求的过滤器
@Component
public class UserInfoFilter extends OncePerRequestFilter {
//注入用户表对应的Service
@Autowired
private SysUserService sysUserService;
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain chain) throws ServletException, IOException {
//编写过滤器
String uri = request.getRequestURI();//获得当前请求路径
if ("/login.html".equals(uri)) {
String username = request.getParameter("username");
SysUser user = sysUserService.getInfoByUsername(username);
request.getSession().setAttribute("user-info", user);
}
chain.doFilter(request, response);
}
}
SysUserService下的getInfoByUsername(username)和getByUsername(String username) (仅供参考)
@Override
public SecurityUser getByUsername(String username) {
//定义个对象,传入用户名
SysUser user=SysUser.builder().username(username).build();
//根据用户名查询数据库,加载用户信息
user= SysUserMapper.list(user).get(0);
//获取用户所有角色
List<SysRole> listRole=sysRoleMapper.getRolesByUserName(username);
//获取用户所有资源
List<SysResources> listResources=sysResourcesMapper.getListByUserName(username);
//创建security相关的权限集合
List<GrantedAuthority> authorities=new ArrayList<>();
for (SysRole role:listRole) {
SimpleGrantedAuthority authority=new SimpleGrantedAuthority(role.getRoleName());//设置相关权限
authorities.add(authority);
}
for (SysResources r:listResources) {
SimpleGrantedAuthority authority=new SimpleGrantedAuthority(r.getResourcesAlias());//设置相关权限
authorities.add(authority);
}
SecurityUser securityUser=new SecurityUser(user.getUsername(),user.getPassword(),authorities);
return securityUser;
}
@Override
public SysUser getInfoByUsername(String username) {
//定义个对象,传入用户名
SysUser user=SysUser.builder().username(username).build();
//根据用户名查询数据库,加载用户信息
user= SysUserMapper.list(user).get(0);
return user;
}
5.根据用户名查找权限的Security帮助类
/**
* 根据用户名查找对应的权限
*/
@Service
public class MyUserDetilSecurity implements UserDetailsService {
@Resource
private SysUserService securityUser;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
return securityUser.getByUsername(s);
}
}
6、在freemarker页面顶部引入标签
<#assign security=JspTaglibs["http://www.springframework.org/security/tags"] />
7、页面标签使用如下:
<@security.authorize access="hasRole('ADMIN')">
菜单名称等
</@security.authorize>
以上内容仅供参考 如有雷同纯属意外 有什么不懂的欢迎大家加我QQ问我 3230530278