1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > springboot+springsecurity基于用户表-角色表-权限表的权限控制(三)

springboot+springsecurity基于用户表-角色表-权限表的权限控制(三)

时间:2018-12-07 18:32:39

相关推荐

springboot+springsecurity基于用户表-角色表-权限表的权限控制(三)

用户实体类

参考:springboot+springsecurity基于角色的权限验证(二)

配置类

@Configuration@EnableWebSecurity@EnableGlobalMethodSecurity(prePostEnabled =true) // 启用授权注解public class SecurityConfiguration extends WebSecurityConfigurerAdapter {@Autowiredprivate MyFilterSecurityInterceptor myFilterSecurityInterceptor;/** 获取数据库中信息存到User对象中 */@Beanpublic UserDetailsService userService(){//注册userService 的beanreturn new UserServiceImpl();}/**加密密码*/@BeanPasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}/**MD5加密密码*/@BeanPasswordEncoder md5PasswordEncoder() {return new MD5PasswordEncoder();}/** 放行静态资源 */@Overridepublic void configure(WebSecurity web) throws Exception {//解决静态资源被拦截的问题web.ignoring().antMatchers("/css/**");web.ignoring().antMatchers("/js/**");web.ignoring().antMatchers("/images/**");web.ignoring().antMatchers("/login/**");//解决服务注册url被拦截的问题web.ignoring().antMatchers("/resources/**");}@Overrideprotected void configure(HttpSecurity http) throws Exception {// 登录http.formLogin().loginPage("/toLogin").loginProcessingUrl("/doLogin").defaultSuccessUrl("/index").failureUrl("/toLogin?error=true"); //解决非thymeleaf的form表单提交被拦截问题http.csrf().disable();http.authorizeRequests().antMatchers("/toLogin").permitAll().anyRequest().authenticated();//session管理//session失效后跳转到登录页面 http.sessionManagement().invalidSessionUrl("/toLogin");//单用户登录,如果有一个登录了,同一个用户在其他地方登录将前一个剔除下线//http.sessionManagement().maximumSessions(1).expiredSessionStrategy(expiredSessionStrategy());//单用户登录,如果有一个登录了,同一个用户在其他地方不能登录http.sessionManagement().maximumSessions(1).maxSessionsPreventsLogin(true);//退出删除cookiehttp.logout().permitAll().logoutUrl("/logout") //执行注销的url.invalidateHttpSession(true) // 指定是否在注销时让httpSession无效.deleteCookies("JESSIONID") // 清除cookie.logoutSuccessUrl("/toLogin"); // 注销成功后跳转的urlsuper.configure(http);//解决中文乱码问题CharacterEncodingFilter filter = new CharacterEncodingFilter();filter.setEncoding("UTF-8");filter.setForceEncoding(true);//http.addFilterBefore(filter,CsrfFilter.class);http.addFilterBefore(myFilterSecurityInterceptor, FilterSecurityInterceptor.class);}/*** 认证器*/@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {// 自定义加密auth.userDetailsService(userService()).passwordEncoder(md5PasswordEncoder());}}

创建决策类 MyAccessDecisionManager

/*** 决策管理器(授权)** @ClassName: MyAccessDecisionManager* @description * @author Jayden* @createDate 4月8日-下午2:02:32*/@Servicepublic class MyAccessDecisionManager implements AccessDecisionManager {/*** decide 方法是判定是否拥有权限的决策方法,* authentication 是释UserService中循环添加到 GrantedAuthority 对象中的权限信息集合.* object 包含客户端发起的请求的requset信息,可转换为 HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();* * configAttributes 为MyInvocationSecurityMetadataSource的getAttributes(Object object)这个方法返回的结果,* 此方法是为了判定用户请求的url 是否在权限表中,如果在权限表中,则返回给 decide 方法,用来判定用户是否有此权限。如果不在权限表中则放行。* */@Overridepublic void decide(Authentication authentication, Object obj, Collection<ConfigAttribute> configAttributes)throws AccessDeniedException, InsufficientAuthenticationException {if(null== configAttributes || configAttributes.size() <= 0) {return;}ConfigAttribute c;String needRole;for(Iterator<ConfigAttribute> iter = configAttributes.iterator(); iter.hasNext(); ) {c = iter.next();needRole = c.getAttribute();//authentication 为在注释1 中循环添加到 GrantedAuthority 对象中的权限信息集合for(GrantedAuthority ga : authentication.getAuthorities()) {if(needRole.trim().equals(ga.getAuthority())) {return;}}}throw new AccessDeniedException("no right");}@Overridepublic boolean supports(ConfigAttribute configattribute) {// TODO Auto-generated method stubreturn true;}@Overridepublic boolean supports(Class<?> class1) {// TODO Auto-generated method stubreturn true;}}

创建类 MyFilterSecurityInterceptor

@Servicepublic class MyFilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter {@Autowiredprivate FilterInvocationSecurityMetadataSource securityMetadataSource;@Autowiredpublic void setMyAccessDecisionManager(MyAccessDecisionManager myAccessDecisionManager) {super.setAccessDecisionManager(myAccessDecisionManager);}@Overridepublic void destroy() {// TODO Auto-generated method stub}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {FilterInvocation fi = new FilterInvocation(request, response, chain);invoke(fi);}public void invoke(FilterInvocation fi) throws IOException, ServletException {// fi里面有一个被拦截的url// 里面调用MyInvocationSecurityMetadataSource的getAttributes(Object// object)这个方法获取fi对应的所有权限// 再调用MyAccessDecisionManager的decide方法来校验用户的权限是否足够InterceptorStatusToken token = super.beforeInvocation(fi);try {// 执行下一个拦截器fi.getChain().doFilter(fi.getRequest(), fi.getResponse());} finally {super.afterInvocation(token, null);}}@Overridepublic void init(FilterConfig arg0) throws ServletException {// TODO Auto-generated method stub}@Overridepublic Class<?> getSecureObjectClass() {// TODO Auto-generated method stubreturn FilterInvocation.class;}@Overridepublic SecurityMetadataSource obtainSecurityMetadataSource() {// TODO Auto-generated method stubreturn this.securityMetadataSource;}}

创建类 MyInvocationSecurityMetadataSourceService

@Servicepublic class MyInvocationSecurityMetadataSourceService implements FilterInvocationSecurityMetadataSource {@Autowiredprivate T_permissionMapper permissionMapper;private HashMap<String, Collection<ConfigAttribute>> map =null;/*** 加载权限表中所有权限*/public void loadResourceDefine(){map = new HashMap<>();Collection<ConfigAttribute> array;ConfigAttribute cfg;// 查询到权限表所有信息List<T_permission> permissions = permissionMapper.findAll();for(T_permission permission : permissions) {array = new ArrayList<>();cfg = new SecurityConfig(permission.getName());/***此处只添加了用户的名字,其实还可以添加更多权限的信息,例如请求方法到ConfigAttribute的集合中去。*此处添加的信息将会作为MyAccessDecisionManager类的decide的第三个参数。*/array.add(cfg);//用权限的getUrl() 作为map的key,用ConfigAttribute的集合作为 value,map.put(permission.getUrl(), array);}}@Overridepublic Collection<ConfigAttribute> getAllConfigAttributes() {// TODO Auto-generated method stubreturn null;}/*** 此方法是为了判定用户请求的url 是否在权限表中,如果在权限表中,则返回给 decide 方法,* 用来判定用户是否有此权限。如果不在权限表中则放行。*/@Overridepublic Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {if(map ==null) loadResourceDefine();//object 中包含用户请求的request 信息HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();AntPathRequestMatcher matcher;String resUrl;for(Iterator<String> iter = map.keySet().iterator(); iter.hasNext(); ) {resUrl = iter.next();matcher = new AntPathRequestMatcher(resUrl);if(matcher.matches(request)) {return map.get(resUrl);}}return null;}@Overridepublic boolean supports(Class<?> class1) {// TODO Auto-generated method stubreturn true;}}

权限 PermissionMapper.xml

用户表,角色表,权限表,用户角色中间表,角色权限中间表

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapper PUBLIC "-////DTD Mapper 3.0//EN" "/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.jayden.mapper.T_permissionMapper"><!-- 通用查询映射结果 --><resultMap id="BaseResultMap" type="com.jayden.entity.T_permission"><id column="id" property="id" /><result column="name" property="name" /><result column="description" property="description" /><result column="url" property="url" /><result column="pid" property="pid" /></resultMap><!-- 通用查询结果列 --><sql id="Base_Column_List">id, name, description, url, pid</sql><!-- 通过userid查询权限信息 --><select id="selectPermsByUserId" resultMap="BaseResultMap">select p.* from t_user u LEFT JOIN t_user_role tur on u.id = tur.user_idLEFT JOIN t_role r on tur.role_id = r.idLEFT JOIN t_role_permission trp on trp.role_id = r.idLEFT JOIN t_permission p on p.id = trp.permission_idwhere u.id=#{userId}</select><!-- 查询所有权限 --><select id="findAll" resultMap="BaseResultMap">select * from t_permission</select>

UserDetailsService 实现类

@Servicepublic class UserServiceImpl extends ServiceImpl<UserMapper, T_user> implements UserService, UserDetailsService {// 用户@Autowiredprivate UserMapper userMapper;// 权限@Autowiredprivate T_permissionMapper permissionMapper;// 加密@Autowiredprivate MD5PasswordEncoder md5PasswordEncoder;/*** 重写springSecurity类方法*/@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {// 通过用户名称获取对象T_user user = userMapper.findByUserName(username);if (user != null) {// 因为数据库中密码是明文的,所以在这里加密了(仅测试使用:123为盐)user.setPassword(md5PasswordEncoder.encode(user.getPassword()+"123"));// 通过用户id获取权限信息List<T_permission> permissions = permissionMapper.selectPermsByUserId(user.getId());List<GrantedAuthority> grantedAuthorities = new ArrayList <>();for (T_permission permission : permissions) {if (permission != null && permission.getName() !=null) {GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(permission.getName());//此处将权限信息添加到 GrantedAuthority 对象中,在后面进行全权限验证时会使用GrantedAuthority 对象grantedAuthorities.add(grantedAuthority);}}return new User(user.getUsername(), user.getPassword(), grantedAuthorities);} else {System.out.println("该用户不存在");throw new UsernameNotFoundException("用户: " + username + " 不存在!");}}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。