网页制作与网站开发从入门到精通 下载,淘客做网站怎么备案,怎么添加字体在wordpress,做游戏网站有几个要素这里写自定义目录标题 引言SpringSecurity之授权授权介绍java权限集成 登录失败三次用户上锁 引言
SpringSecurity深度解析与实践#xff08;2#xff09;的网址
SpringSecurity之授权
授权介绍
Spring Security 中的授权分为两种类型#xff1a;
基于角色的授权#… 这里写自定义目录标题 引言SpringSecurity之授权授权介绍java权限集成 登录失败三次用户上锁 引言
SpringSecurity深度解析与实践2的网址
SpringSecurity之授权
授权介绍
Spring Security 中的授权分为两种类型
基于角色的授权以用户所属角色为基础进行授权如管理员、普通用户等通过为用户分配角色来控制其对资源的访问权限。基于资源的授权以资源为基础进行授权如 URL、方法等通过定义资源所需的权限来控制对该资源的访问权限。
Spring Security 提供了多种实现授权的机制最常用的是使用基于注解的方式建立起访问资源和权限之间的映射关系。
其中最常用的两个注解是 Secured 和 PreAuthorize。Secured 注解是更早的注解基于角色的授权比较适用PreAuthorize 基于 SpEL 表达式的方式可灵活定义所需的权限通常用于基于资源的授权。
java权限集成
WebSecurityConfig配置类
package com.yuan.springsecurity1.config;import com.fasterxml.jackson.databind.ObjectMapper;
import com.yuan.springsecurity1.resp.JsonResponseBody;
import com.yuan.springsecurity1.resp.JsonResponseStatus;
import com.yuan.springsecurity1.service.impl.UserServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;import javax.sql.DataSource;Configuration
//开启SpringSecurity的默认行为
EnableWebSecurity
EnableGlobalMethodSecurity(prePostEnabled true)
public class WebSecurityConfig {Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}Autowiredprivate DataSource dataSource;/*** 配置持久化Token方式注意tokenRepository.setCreateTableOnStartup()配置*/Beanpublic PersistentTokenRepository persistentTokenRepository(){JdbcTokenRepositoryImpl tokenRepository new JdbcTokenRepositoryImpl();tokenRepository.setDataSource(dataSource);// 设置为true要保障数据库该表不存在不然会报异常哦// 所以第二次打开服务器应用程序的时候得把它设为falsetokenRepository.setCreateTableOnStartup(false);return tokenRepository;}Autowiredprivate MyUserDetailsService myUserDetailsService;AutowiredObjectMapper objectMapper;AutowiredMyAuthenticationFailureHandler myAuthenticationFailureHandler;/*** 获取AuthenticationManager认证管理器登录时认证使用基于数据库方式* param* return* throws Exception*/Beanpublic AuthenticationManager authenticationManager() throws Exception {//创建DaoAuthenticationProviderDaoAuthenticationProvider providernew DaoAuthenticationProvider();//设置userDetailsService基于数据库方式进行身份认证provider.setUserDetailsService(myUserDetailsService);//配置密码编码器provider.setPasswordEncoder(passwordEncoder());return new ProviderManager(provider);}Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http)throws Exception{http.authorizeRequests()// 开放接口访问权限不需要登录就可以访问.antMatchers(/toLogin).permitAll()//访问路径有admin的方法时需要有ADMIN的身份
// .antMatchers(/admin/**).hasRole(ADMIN)
// .antMatchers(/user/**).hasAnyRole(ADMIN,USER)// 其余所有请求全部需要鉴权认证.anyRequest().authenticated().and().formLogin()// 设置登录页面的 URL.loginPage(/toLogin)// 设置登录请求的 URL即表单提交的 URL.loginProcessingUrl(/userLogin)// 设置登录表单中用户名字段的参数名默认为username.usernameParameter(username)// 设置登录表单中密码字段的参数名默认为password.passwordParameter(password)//成功后的处理.successHandler((req,resp,auth)-{
// resp.sendRedirect(/index);Object user auth.getPrincipal();objectMapper.writeValue(resp.getOutputStream(), JsonResponseBody.success(user));})//登录失败的处理.failureHandler(myAuthenticationFailureHandler).and().exceptionHandling()
// .accessDeniedPage(/noAccess)//权限不够处理.accessDeniedHandler((req,resp,ex)-{objectMapper.writeValue(resp.getOutputStream(),JsonResponseBody.other(JsonResponseStatus.NO_ACCESS));})//没有认证(登录)处理.authenticationEntryPoint((req,resp,ex)-{objectMapper.writeValue(resp.getOutputStream(),JsonResponseBody.other(JsonResponseStatus.NO_LOGIN));}).and().logout()// 设置安全退出的URL路径.logoutUrl(/logout)// 设置退出成功后跳转的路径.logoutSuccessUrl(/toLogin).and().rememberMe()// 指定 rememberMe 的参数名用于在表单中携带 rememberMe 的值。.rememberMeParameter(remember-me)// 指定 rememberMe 的有效期单位为秒默认2周。.tokenValiditySeconds(600)// 指定 rememberMe 的 cookie 名称。.rememberMeCookieName(remember-me-cookie)// 指定 rememberMe 的 token 存储方式可以使用默认的 PersistentTokenRepository 或自定义的实现。.tokenRepository(persistentTokenRepository())// 指定 rememberMe 的认证方式需要实现 UserDetailsService 接口并在其中查询用户信息。.userDetailsService(myUserDetailsService);
// http.csrf().disable();return http.build();}
}登录权限绑定
package com.yuan.springsecurity1.config;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
import com.yuan.springsecurity1.pojo.*;
import com.yuan.springsecurity1.mapper.UserMapper;
import com.yuan.springsecurity1.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;/*** p* 用户信息表 服务实现类* /p** author yuan* since 2023-12-21*/
Component
public class MyUserDetailsService implements UserDetailsService {Autowiredprivate IUserService iUserService;Autowiredprivate IUserRoleService iUserRoleService;Autowiredprivate IRoleService iRoleService;Autowiredprivate IRoleModuleService iRoleModuleService;Autowiredprivate IModuleService iModuleService;Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {User user iUserService.getOne(new QueryWrapperUser().eq(username, username));if(usernull)throw new UsernameNotFoundException(用户名无效);//查询所有的身份,map 遍历数据对象返回的数据放到一个新的流中collect(Collectors.toList())用list集合接收ListInteger userIds iUserRoleService.list(new QueryWrapperUserRole().eq(user_id, user.getId())).stream().map(UserRole::getRoleId).collect(Collectors.toList());//根据role_id拿到身份名称集合ListString roleNames iRoleService.list(new QueryWrapperRole().in(role_id, userIds)).stream().map(Role::getRoleName).collect(Collectors.toList());//根据身份id role_id拿到权限id module_idListInteger moduleIds iRoleModuleService.list(new QueryWrapperRoleModule().in(role_id, userIds)).stream().map(RoleModule::getModuleId).collect(Collectors.toList());//根据权限id拿到对应的urlListString urls iModuleService.list(new QueryWrapperModule().in(id, moduleIds)).stream().map(Module::getUrl).filter(Objects::nonNull).collect(Collectors.toList());roleNames.addAll(urls);ListSimpleGrantedAuthority authorities roleNames.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList());user.setAuthorities(authorities);return user;}
}
Controller类数据 ResponseBodyRequestMapping(/o_f)PreAuthorize(hasAnyAuthority(order:manager:analysis))public String o_f() {return 订单分析;}ResponseBodyRequestMapping(/b_add)PreAuthorize(hasAnyAuthority(book:manager:add))public String b_add() {return 书籍新增;}需要添加一个规则判断是否有权限我这个放在WebSecurityConfig类上
EnableGlobalMethodSecurity(prePostEnabled true)登录失败三次用户上锁
搭配WebSecurityConfig类中失败的对象
package com.yuan.springsecurity1.config;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yuan.springsecurity1.pojo.User;
import com.yuan.springsecurity1.resp.JsonResponseBody;
import com.yuan.springsecurity1.resp.JsonResponseStatus;
import com.yuan.springsecurity1.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** author 叶秋* site* company 卓京公司* create 2023-12-23 23:21*/
Component
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {AutowiredObjectMapper objectMapper;Autowiredprivate IUserService iUserService;Overridepublic void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {if(12){ //假设超过三次失败User user iUserService.getOne(new QueryWrapperUser().eq(username, request.getParameter(username)));user.setAccountNonLocked(false);iUserService.updateById(user);}objectMapper.writeValue(response.getOutputStream(), JsonResponseBody.other(JsonResponseStatus.LOGIN_FAILURE));}
}