当前位置: 首页 > news >正文

启明星网站建设做网站怎么制作

启明星网站建设,做网站怎么制作,黄埔区网站建设,律师网站建设品牌基础概念 什么是认证 认证#xff1a;用户认证就是判断一个用户的身份身份合法的过程#xff0c;用户去访问系统资源的时候系统要求验证用户的身份信息#xff0c;身份合法方可继续访问#xff0c;不合法则拒绝访问。常见的用户身份认证方式有#xff1a;用户密码登录用户认证就是判断一个用户的身份身份合法的过程用户去访问系统资源的时候系统要求验证用户的身份信息身份合法方可继续访问不合法则拒绝访问。常见的用户身份认证方式有用户密码登录二维码登录手机短信登录指纹认证等方式。 其中Spring Security使用的是OAuth2.0认证授权协议。 什么是会话 用户认证通过后为了避免用户的每次操作都进行认证可将用户的信息保存到会话中会话就是系统为了保持用户当前用户的登录状态所提供的机制常见的有基于Session的方式、基于token等方式 基于Session的认证方式 他的交互流程是用户认证成功后在服务端生成用户相关的数据保存在session当前会话中,发给客户端的session_id存放到cookie中这样用户客户端请求时带上session_id就可以验证服务器是否存在session数据以此完成用户的合法校验。当用户退出系统或session过期销毁时客户端的session_id就无效。 方法含义HttpSession getSession(Boolean create)获取当前HttpSession对象void setAttribute(String name, Object value)向session中存放对象void removeAttribute(String name)移除session中的对象Object getAttribute(String name)从session中获取对象 基于Token方式 他的交互流程是用户认证成功后服务端生成一个token发送给客户端客户端可以放到Cookie中或localStorage等存储中每次请求时带上token服务端收到的token通过验证后即可确认用户身份。 对比总结 基于session的认证方式有servlet规范定制的服务端要存储session信息都要占用内存资源客户端需要支持Cookie基于token的方式则一般不需要服务器存储token并且不限制客户端的存储方式。如今移动互联网时代更多类型的用户端需要接入系统系统多是采用前后端分离的架构进行实现所以基于token的方式更合理。 什么是授权 授权授权是用户认证通过根据用户的权限来控制用户访问资源的过程拥有资源的访问权限则正常访问没有权限则拒绝访问。 授权数据模型 授权可简单理解为who对whatwhich进行how操作。包括如下 1、who即主体主体一般指用户也可以是程序需要访问系统中的资源。 2、what即资源如系统菜单页面按钮代码方法系统商品信息系统订单等。系统菜单页面按钮代码方法属于系统功能资源对于web系统每个资源通常对应一个URL,系统商品信息、订单信息等属于实体资源数据资源实体资源由资源类型和资源示例组成比如商品信息为资源类型商品编号如001为资源的实例 3、how权限/许可Permission,规定了用户对资源的操作许可权限离开资源没有意义如用户查询权限用户添加权限某个代码方法的调用权限编号为001的用户修改权限等通过权限可知用户对哪些资源都有哪些许可操作。 主体、资源、权限关系如下图 企业开发中权限表设计如下 资源资源ID、资源名称、访问地址 权限资源ID、权限标识、权限名称、资源ID 合并为 权限权限ID、权限标识、权限名称、资源名称、资源访问地址 数据模型之间的关系如下 RBAC 基于角色访问控制 RBAC基于角色的访问控制Role-Based Access Control是按角色进行授权比如主体的角色为总经理可以查询企业运营报表查询员工工资信息等访问控制流程如下 #mermaid-svg-fsYyAk15Ci4QlE2x {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-fsYyAk15Ci4QlE2x .error-icon{fill:#552222;}#mermaid-svg-fsYyAk15Ci4QlE2x .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-fsYyAk15Ci4QlE2x .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-fsYyAk15Ci4QlE2x .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-fsYyAk15Ci4QlE2x .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-fsYyAk15Ci4QlE2x .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-fsYyAk15Ci4QlE2x .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-fsYyAk15Ci4QlE2x .marker{fill:#333333;stroke:#333333;}#mermaid-svg-fsYyAk15Ci4QlE2x .marker.cross{stroke:#333333;}#mermaid-svg-fsYyAk15Ci4QlE2x svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-fsYyAk15Ci4QlE2x .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-fsYyAk15Ci4QlE2x .cluster-label text{fill:#333;}#mermaid-svg-fsYyAk15Ci4QlE2x .cluster-label span{color:#333;}#mermaid-svg-fsYyAk15Ci4QlE2x .label text,#mermaid-svg-fsYyAk15Ci4QlE2x span{fill:#333;color:#333;}#mermaid-svg-fsYyAk15Ci4QlE2x .node rect,#mermaid-svg-fsYyAk15Ci4QlE2x .node circle,#mermaid-svg-fsYyAk15Ci4QlE2x .node ellipse,#mermaid-svg-fsYyAk15Ci4QlE2x .node polygon,#mermaid-svg-fsYyAk15Ci4QlE2x .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-fsYyAk15Ci4QlE2x .node .label{text-align:center;}#mermaid-svg-fsYyAk15Ci4QlE2x .node.clickable{cursor:pointer;}#mermaid-svg-fsYyAk15Ci4QlE2x .arrowheadPath{fill:#333333;}#mermaid-svg-fsYyAk15Ci4QlE2x .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-fsYyAk15Ci4QlE2x .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-fsYyAk15Ci4QlE2x .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-fsYyAk15Ci4QlE2x .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-fsYyAk15Ci4QlE2x .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-fsYyAk15Ci4QlE2x .cluster text{fill:#333;}#mermaid-svg-fsYyAk15Ci4QlE2x .cluster span{color:#333;}#mermaid-svg-fsYyAk15Ci4QlE2x div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-fsYyAk15Ci4QlE2x :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}yes继续访问no查询工资信息判断主体是否具有总经理角色无法访问处理基于资源访问控制 RBAC基于资源的访问控制Resource-Based Access Control是按资源或权限进行授权比如用户必须具有查询工资权限才能查询员工工资信息等访问控制流程如下 #mermaid-svg-Zd2u1I1bBvvjYiJH {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-Zd2u1I1bBvvjYiJH .error-icon{fill:#552222;}#mermaid-svg-Zd2u1I1bBvvjYiJH .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Zd2u1I1bBvvjYiJH .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-Zd2u1I1bBvvjYiJH .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Zd2u1I1bBvvjYiJH .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Zd2u1I1bBvvjYiJH .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Zd2u1I1bBvvjYiJH .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Zd2u1I1bBvvjYiJH .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Zd2u1I1bBvvjYiJH .marker.cross{stroke:#333333;}#mermaid-svg-Zd2u1I1bBvvjYiJH svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Zd2u1I1bBvvjYiJH .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Zd2u1I1bBvvjYiJH .cluster-label text{fill:#333;}#mermaid-svg-Zd2u1I1bBvvjYiJH .cluster-label span{color:#333;}#mermaid-svg-Zd2u1I1bBvvjYiJH .label text,#mermaid-svg-Zd2u1I1bBvvjYiJH span{fill:#333;color:#333;}#mermaid-svg-Zd2u1I1bBvvjYiJH .node rect,#mermaid-svg-Zd2u1I1bBvvjYiJH .node circle,#mermaid-svg-Zd2u1I1bBvvjYiJH .node ellipse,#mermaid-svg-Zd2u1I1bBvvjYiJH .node polygon,#mermaid-svg-Zd2u1I1bBvvjYiJH .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Zd2u1I1bBvvjYiJH .node .label{text-align:center;}#mermaid-svg-Zd2u1I1bBvvjYiJH .node.clickable{cursor:pointer;}#mermaid-svg-Zd2u1I1bBvvjYiJH .arrowheadPath{fill:#333333;}#mermaid-svg-Zd2u1I1bBvvjYiJH .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Zd2u1I1bBvvjYiJH .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Zd2u1I1bBvvjYiJH .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-Zd2u1I1bBvvjYiJH .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-Zd2u1I1bBvvjYiJH .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Zd2u1I1bBvvjYiJH .cluster text{fill:#333;}#mermaid-svg-Zd2u1I1bBvvjYiJH .cluster span{color:#333;}#mermaid-svg-Zd2u1I1bBvvjYiJH div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Zd2u1I1bBvvjYiJH :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}YES继续访问NO查询工资信息判断主体身份具有查询工资的权限无权访问Spring Security 简介 Spring Security是基于Spring框架提供一套web应用安全性解决方案。一般来说web应用的安全性主要包括用户认证Authentication和用户授权Authorization两部分。这两点是Spring Security的核心功能。 用户认证是验证某个用户是否为系统中的合法主体也就是用户能否访问该系统。 用户授权是验证某个用户是否有权限执行某个操作。在一个系统中不同的用户所具有的权限不同的。 spring security在项目中进行应用的时候需要登录才能访问接口否则401.默认用户名user密码每次启动项目后自动生成在日志中输出 引入Maven依赖 dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-security/artifactId /dependency快速开始 在controller中编写对应的java代码 RestController RequestMapping(/test) public class TestController {GetMapping(/add)public String add() {return hello world;} }浏览器访问该接口需要输入用户名以及密码默认用户名是user,密码有控制台日志输出 postman调用接口需要在Athorization中输入用户名以及密码,注意Type选择的是Basic Auth 自定义用户名密码 可以在application.yml文件中添加以下配置即可实现 spring:security:user:name: userpassword: pwd123除此之外还可以实现UserDetailsService接口来实现自定义用户名密码 配置类 Configuration public class SecurityConfiguration {Beanpublic PasswordEncoder getPasswordEncode() {return new BCryptPasswordEncoder();} }使用BCryptPasswordEncoder来对密码进行加密 UserDetailsService实现类 Service public class UserDetailServiceImpl implements UserDetailsService {Value(${application.customize.username:admin})private String customizeUsername;Value(${application.customize.password:123})private String customizePassword;Value(${application.customize.permission.list:admin,normal})private String permissionList;Resourceprivate PasswordEncoder passwordEncoder;Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {// 查询用户名是否在数据存在,如果不存在抛出异常if (!customizeUsername.equals(username)) {throw new UsernameNotFoundException(用户名不存在: {} username);}// 如果查询到密码的密码进行解析,或者总结把密码传入构造方法String password passwordEncoder.encode(customizePassword);// 使用AuthorityUtils构造权限列表return new User(username, password, AuthorityUtils.commaSeparatedStringToAuthorityList(permissionList));} }注意最忌代码里写死字符串,尽可能的进行配置 配置文件 application:customize:username: adminpassword: 123permission:list: admin,normal自定义登录页 在resources文件夹下创建一个static文件夹同时创建login.html、error.html、main.html页面。在SecurityConfiguration中继承WebSecurityConfigurerAdapter并重写configure(HttpSecurity httpSecurity)方法 配置类代码如下 Configuration public class SecurityConfiguration extends WebSecurityConfigurerAdapter {/*** 将Spring Security默认的登录页面路由到自定义的登录页面.* 由于重写了configure方法,所以需要codehttpSecurity.authorizeRequests()* .anyRequest().authenticated();/code来进行所有请求的拦截验证。* 同时需要对login.html进行放行不需要验证。同时对/login请求进行* 拦截,登录成功后会跳转到main.html,登录失败跳转到error.html。* 同时需要关闭csrf防护.* param httpSecurity* throws Exception*/Overrideprotected void configure(HttpSecurity httpSecurity) throws Exception {httpSecurity.formLogin().loginProcessingUrl(/login).loginPage(/login.html).successForwardUrl(/toMain).failureForwardUrl(/toError);httpSecurity.authorizeRequests().antMatchers(/error.html).permitAll().antMatchers(/login.html).permitAll().anyRequest().authenticated();httpSecurity.csrf().disable();}Beanpublic PasswordEncoder getPasswordEncode() {return new BCryptPasswordEncoder();} }注意在一些前后端分离的项目中这种配置是无法实现对应的需求 前后端分离自定义登录页 实现接口AuthenticationSuccessHandler并实现接口的中方法将登录成功后的页面重定向到对应的url 代码示例 public class SecurityAuthenticationSuccessHandler implements AuthenticationSuccessHandler {private String url;public SecurityAuthenticationSuccessHandler(String url) {this.url url;}/*** 前后端分离进行重定向* param httpServletRequest* param httpServletResponse* param authentication* throws IOException* throws ServletException*/Overridepublic void onAuthenticationSuccess(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse,Authentication authentication) throws IOException, ServletException {httpServletResponse.sendRedirect(url);} }登录失败就实现接口AuthenticationFailureHandler同时实践其中的方法 代码示例 public class SecurityAuthenticationFailureHandler implements AuthenticationFailureHandler {private String url;public SecurityAuthenticationFailureHandler(String url) {this.url url;}Overridepublic void onAuthenticationFailure(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse,AuthenticationException e) throws IOException, ServletException {httpServletResponse.sendRedirect(url);} }配置类 继承WebSecurityConfigurerAdapter重写configure(HttpSecurity httpSecurity)方法 Overrideprotected void configure(HttpSecurity httpSecurity) throws Exception {httpSecurity.formLogin().loginProcessingUrl(/login).loginPage(/login.html) // .successForwardUrl(/toMain)// 登陆成功重定向到https://www.baidu.com.successHandler(new SecurityAuthenticationSuccessHandler(https://www.baidu.com)) // .failureForwardUrl(/toError);// 登录失败重定向到error.html.failureHandler(new SecurityAuthenticationFailureHandler(/error.html));httpSecurity.authorizeRequests().antMatchers(/error.html).permitAll().antMatchers(/login.html).permitAll().anyRequest().authenticated();httpSecurity.csrf().disable();}antMatcher 方法定义 public C antMatchers(String... antPatterns)参数是不定向参数每个参数是一个ant表达式用于匹配url 规则如下 1、?匹配一个字符 2、*匹配0个或多个字符 3、**匹配0个或多个目录 在实际项目中经常需要放行所有的静态资源如下 .antMatchers(/js/**,/css/**).permitAll()还有一种配置方式是只是.js文件都放行 .antMatchers(/**/*.js).permitAll()regexMatchers 方法定义 public C regexMatchers(String... regexPatterns)regexMatchers使用的是正则表达式来匹配对应的资源进行权限校验。除此之外还有通过HttpMethod来限定匹配的请求类型如下 httpSecurity.authorizeRequests().regexMatchers(HttpMethod.POST,/demo).permitAll()// 所有请求都会被认证.anyRequest().authenticated();mvcMatchers 方法定义 public ExpressionUrlAuthorizationConfigurerH.MvcMatchersAuthorizedUrl mvcMatchers(String... patterns) mvcMatchers是用来匹配在配置文件中配置的servlet.path如下 spring:mvc:servlet:path: /securityhttpSecurity.authorizeRequests().mvcMatchers(/hello).servletPath(/security).permitAll()// 所有请求都会被认证.anyRequest().authenticated();权限控制 权限控制一般需要实现UserDetailsService接口中的loadUserByUsername方法并在其中设置需要的权限列表如下 Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {// 查询用户名是否在数据存在,如果不存在抛出异常if (!customizeUsername.equals(username)) {throw new UsernameNotFoundException(用户名不存在: {} username);}// 如果查询到密码的密码进行解析,或者总结把密码传入构造方法String password passwordEncoder.encode(customizePassword);// 使用AuthorityUtils构造权限列表return new User(username, password, AuthorityUtils.commaSeparatedStringToAuthorityList(permissionList));}其中permissionList就是权限列表我使用的是Value注解进行注入如下 Value(${application.customize.permission.list:admin,normal}) private String permissionList;配置类 在配置类中继承WebSecurityConfigurerAdapter重写configure方法可以对其进行权限控制。如admin.html页面只能admin进行访问那么配置如下: httpSecurity.authorizeRequests().antMatchers(/admin.html).hasAnyAuthority(admin)// 所有请求都会被认证.anyRequest().authenticated();其中admin就是在配置类中的权限列表 角色配置 同上编写service实现类并继承UserDetailsService中的loadUserByUsername方法并配置权限列表但权限列表配置如下 Value(${application.customize.permission.list:admin,normal,ROLE_hello}) private String permissionList;其中的ROLE_hello就代表角色配置注意一定要以ROLE_开头否则Spring Security无法识别。 配置类 httpSecurity.authorizeRequests().antMatchers(/role.html).hasAnyRole(hello)// 所有请求都会被认证.anyRequest().authenticated();这里使用的是hasAnyRole进行角色控制 IP地址判断 这里的ip地址指的是用户浏览器输入的地址比如localhost是本机的地址也可以是127.0.0.1也可以是Windows cmd的ipconfig命令的ip地址 配置类 httpSecurity.authorizeRequests().antMatchers(/main.html).hasIpAddress(127.0.0.1)// 所有请求都会被认证.anyRequest().authenticated();这里配置的127.0.0.1只能在浏览器输入127.0.0.1才有效输入localhost或Windows cmd的ipconfig命令的ip地址均无法访问。 自定义403处理 编写自定义类SecurityAccessDeniedHandler同时实现接口AccessDeniedHandler实现handle方法 Handler配置 Component public class SecurityAccessDeniedHandler implements AccessDeniedHandler {/*** 设置响应的状态码处理403状态码请求,同时* 设置请求头并返回json字符串* param httpServletRequest* param httpServletResponse* param e* throws IOException* throws ServletException*/Overridepublic void handle(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse,AccessDeniedException e) throws IOException, ServletException {httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);httpServletResponse.setHeader(Content-Type, application/json;charsetutf-8);Cleanup PrintWriter writer httpServletResponse.getWriter();writer.write({\status\: \error\, \message\: \权限不足请联系管理员\});writer.flush();} }编写配置类SecurityConfiguration继承WebSecurityConfigurerAdapter重写configure方法 配置类 Override protected void configure(HttpSecurity httpSecurity) throws Exception {httpSecurity.formLogin().loginProcessingUrl(/login).loginPage(/login.html).successHandler(new SecurityAuthenticationSuccessHandler(/main.html))// 登录失败重定向到error.html.failureHandler(new SecurityAuthenticationFailureHandler(/error.html));httpSecurity.authorizeRequests()// 可以写多条对不同的url进行权限认证.antMatchers(/error.html)// 允许访问的权限.permitAll().antMatchers(/login.html).permitAll()// 所有请求都会被认证.anyRequest().authenticated();httpSecurity.csrf().disable();httpSecurity.exceptionHandling().accessDeniedHandler(securityAccessDeniedHandler); }httpSecurity.exceptionHandling().accessDeniedHandler(securityAccessDeniedHandler);设置自定义的AccessDeniedHandler 基于表达式的访问控制 Access方法使用 登录用户权限判断实际上底层实现都是调用access(表达式) 表达式描述hasRole(String role)如果当前主体具有指定角色则返回true。例子hasRole(admin)默认情况下如果提供的角色不以 开头ROLE_则会添加它。defaultRolePrefix您可以通过修改on来自定义此行为DefaultWebSecurityExpressionHandler。hasAnyRole(String… roles)如果当前主体具有任何提供的角色以逗号分隔的字符串列表形式给出则返回true。例子hasAnyRole(admin, user)。hasAuthority(String authority)如果当前委托人具有指定的权限则返回true。hasAnyAuthority(String… authorities)如果当前主体具有任何提供的权限以逗号分隔的字符串列表形式给出则返回true。例子hasAnyAuthority(read, write)。principal允许直接访问代表当前用户的主体对象。authentication允许直接访问Authentication从SecurityContext.permitAll始终评估为true.denyAll始终评估为false.isAnonymous()如果当前主体是匿名用户则返回true。isRememberMe()如果当前主体是记住我的用户则返回true。isAuthenticated()如果用户不是匿名用户则返回true。isFullyAuthenticated()如果用户不是匿名用户且不是记住我的用户则返回true。hasPermission(Object target, Object permission)如果用户有权访问给定权限的提供目标则返回true。例如hasPermission(domainObject, read)hasPermission(Object targetId, String targetType, Object permission)如果用户有权访问给定权限的提供目标则返回true。例如hasPermission(1, com.example.domain.Message, read)。 Access自定义权限控制 编写自定义接口以及自定义方法 public interface SecurityService {Boolean hasPermission(HttpServletRequest httpServletRequest,Authentication authentication); }编写对应的实现类注意要注册为Spring的一个Bean Service public class SecurityServiceImpl implements SecurityService {Overridepublic Boolean hasPermission(HttpServletRequest httpServletRequest,Authentication authentication) {// 获取主体Object object authentication.getPrincipal();if (object instanceof UserDetails) {UserDetails userDetails (UserDetails) object;// 获取权限Collection? extends GrantedAuthority authorities userDetails.getAuthorities();// 判断权限是否存在对应的URIreturn authorities.contains(new SimpleGrantedAuthority(httpServletRequest.getRequestURI()));}return false;} }通过获取主体以及对应的URI来编写对应的权限 通过httpSecurity.authorizeRequests()..anyRequest().access();方法来调用自定义的SecurityServiceImpl中的自定义hasPermission方法 配置类 Overrideprotected void configure(HttpSecurity httpSecurity) throws Exception {httpSecurity.formLogin().loginProcessingUrl(/login).loginPage(/login.html).successHandler(new SecurityAuthenticationSuccessHandler(/main.html))// 登录失败重定向到error.html.failureHandler(new SecurityAuthenticationFailureHandler(/error.html));httpSecurity.authorizeRequests()// 可以写多条对不同的url进行权限认证.antMatchers(/error.html)// 允许访问的权限.permitAll().antMatchers(/login.html).permitAll().anyRequest()// 注意是beanName不是类名.access(securityServiceImpl.hasPermission(request, authentication));httpSecurity.csrf().disable();httpSecurity.exceptionHandling().accessDeniedHandler(securityAccessDeniedHandler);}自定义配置类继承WebSecurityConfigurerAdapter类重写configure方法。值得注意的是在登录成功后会跳转到main.html页面但由于自定义的Access中没有main.thml所以登录成功后会403。 解决方法 Service public class UserDetailServiceImpl implements UserDetailsService {Value(${application.customize.username:admin})private String customizeUsername;Value(${application.customize.password:123})private String customizePassword;Value(${application.customize.permission.list:admin,normal,ROLE_hello,/main.html})private String permissionList;Resourceprivate PasswordEncoder passwordEncoder;Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {// 查询用户名是否在数据存在,如果不存在抛出异常if (!customizeUsername.equals(username)) {throw new UsernameNotFoundException(用户名不存在: {} username);}// 如果查询到密码的密码进行解析,或者总结把密码传入构造方法String password passwordEncoder.encode(customizePassword);// 使用AuthorityUtils构造权限列表return new User(username, password, AuthorityUtils.commaSeparatedStringToAuthorityList(permissionList));} }在permissionList加入/main.html即可 基于注解的访问控制 在Spring Security中提供了一些访问控制的注解。这些注解都是默认不可用的需要通过EnableGlobalMethodSecurity进行开启后使用 如果设置条件允许程序正常运行如果不允许会报500如下 org.springframework.security.access.AccessDeniedException:不允许访问这些注解可以写到Service接口或方法上也可以写到Controller或Controller的方法上。通常情况下都是卸载控制器方法上。控制器接口URL是否允许被访问 Secured注解 Secured是专门用于判断是否具有角色的。能写在方法或类上。参数以ROLE_开头 启动类添加EnableGlobalMethodSecurity(securedEnabled true) SpringBootApplication EnableGlobalMethodSecurity(securedEnabled true) public class SpringSecurityStudyApplication {public static void main(String[] args) {SpringApplication.run(SpringSecurityStudyApplication.class, args);} }注意这里的配置类不能配置successHandler以及failureHandler 接口Controller添加Secured Secured(ROLE_hello) PostMapping(/toMain) public String toMain() {return redirect:main.html; }即角色为hello的用户才可以访问该接口角色由实现接口UserDetailsService重写loadUserByUsername方法中即可实现 PreAuthorize以及PostAuthorize PreAuthorize和PostAuthorize都是方法或类级别的注解 PreAuthorize:表示访问方法或类在执行之前判断权限大多数情况下都是使用这个注解注解的参数和access()方法参数取值相同都是权限表达式 PostAuthorize:表示方法或类执行结束后判断权限该注解很少被使用 启动类添加EnableGlobalMethodSecurity(prePostEnabled true)接口Controller添加PreAuthorize PreAuthorize(hasRole(world)) PostMapping(/toMain) public String toMain() {return redirect:main.html; }注意同样在配置类中的configure方法不能配置successHandler以及failureHandler RememberMe Spring Security中的RememberMe用户只需要在登录时添加remember me复选框取值为true即可将用户信息存储到数据库中以后就可以不登录访问了 添加依赖 dependencygroupIdorg.mybatis.spring.boot/groupIdartifactIdmybatis-spring-boot-starter/artifactIdversion2.1.3/version /dependency dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactId /dependencyapplication.yml配置 spring:datasource:url: jdbc:mysql://localhost:3306/security?userUnicodetruecharseterEncodingUTF-8serverTimezoneAsia/Shanghaidriver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: 123456注入PersistentTokenRepository Bean public PersistentTokenRepository getPersistentTokenRepository() {JdbcTokenRepositoryImpl jdbcTokenRepository new JdbcTokenRepositoryImpl();jdbcTokenRepository.setDataSource(dataSource);// 自动建表,第一次启动需要,第二次启动需要启动// jdbcTokenRepository.setCreateTableOnStartup(true);return jdbcTokenRepository; }继承WebSecurityConfigurerAdapter类重写configure方法的配置如下 Override protected void configure(HttpSecurity httpSecurity) throws Exception {httpSecurity.formLogin().loginProcessingUrl(/login).loginPage(/login.html).successForwardUrl(/toMain).failureForwardUrl(/toError);httpSecurity.authorizeRequests()// 可以写多条对不同的url进行权限认证.antMatchers(/error.html)// 允许访问的权限.permitAll().antMatchers(/login.html).permitAll().anyRequest().authenticated();httpSecurity.csrf().disable();httpSecurity.exceptionHandling().accessDeniedHandler(securityAccessDeniedHandler);httpSecurity.rememberMe().userDetailsService(userDetailServiceImpl)// 持久层对象.tokenRepository(persistentTokenRepository); }前端HTML页面修改如下 form action/login methodpost用户名:input typetext nameusername/br/密码:input typepassword namepassword/br/记住我input typecheckbox nameremember-me valuetruebr/input typesubmit value登录/ /form注意这里的name一定是remember-mevalue为true。登录后在数据库的表里会发现录入有一条数据该失效时间默认是两周修改默认失效时间以及remember-me的别名如下 httpSecurity.rememberMe()// 失效时间,单位:秒.tokenValiditySeconds(60)// 设置remember-me的别名.rememberMeParameter(remember-me-alias).userDetailsService(userDetailServiceImpl)// 持久层对象.tokenRepository(persistentTokenRepository);CSRF CSRF(Cross-site request forgery)跨站请求伪造也称为OneClick Attack或者Session Riding。通过伪造用户请求访问受信任站点的非法请求 跨域只要网络协议、IP地址、端口中任何一个不相同就是跨域请求 客户端与服务进行交互时由于Http协议是无状态的协议所以引入了Cookie进行记录客户端身份。在Cookie中会存放Session ID用来识别客户端的身份。在跨域情况下session id可能被第三方恶意劫持通过这个Session id向服务器发起请求时服务端会认为该请求是合法的可能发生很多意想不到的事情。 Spring Security中的CSRF 从Spring Security4开始CSRF防护默认开启默认会拦截请求。进行CSRF处理。CSRF为了保证不是其他第三方网站访问要求访问时同时携带参数名为_csrf值为token(token在服务器产生的)的内容如果token和服务器的token匹配成功则访问成功。 示例 引入thymeleaf依赖 dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-thymeleaf/artifactIdversion3.0.4/version /dependency dependencygroupIdorg.thymeleaf/groupIdartifactIdthymeleaf-spring5/artifactId /dependency dependencygroupIdorg.thymeleaf.extras/groupIdartifactIdthymeleaf-extras-java8time/artifactId /dependency配置类 配置类继承WebSecurityConfigurerAdapter重写configure方法并放行对应的请求 protected void configure(HttpSecurity httpSecurity) throws Exception {httpSecurity.formLogin().loginProcessingUrl(/login).loginPage(/showLogin).successForwardUrl(/toMain).failureForwardUrl(/toError);httpSecurity.authorizeRequests()// 可以写多条对不同的url进行权限认证.antMatchers(/error.html)// 允许访问的权限.permitAll().antMatchers(/showLogin).permitAll()// 所有请求都会被认证.anyRequest().authenticated();// httpSecurity.csrf().disable();httpSecurity.exceptionHandling().accessDeniedHandler(securityAccessDeniedHandler);httpSecurity.rememberMe()// 失效时间,单位:秒.tokenValiditySeconds(60).userDetailsService(userDetailServiceImpl)// 持久层对象.tokenRepository(persistentTokenRepository);httpSecurity.logout().logoutSuccessUrl(/logout);}关闭Spring Security CSRF Controller跳转到视图 RequestMapping(/showLogin) public String showLogin() {return login; }该视图跳转到resources/templates/login.html下的页面 thymeleaf页面 form action/login methodpostinput typehidden th:value${_csrf.token} name_csrf th:if${_csrf}/用户名:input typetext nameusername/br/密码:input typepassword namepassword/br/记住我input typecheckbox nameremember-me valuetruebr/input typesubmit value登录/ /forminput typehidden th:value${_csrf.token} name_csrf th:if${_csrf}/是表单提交时携带_csrf
http://www.dnsts.com.cn/news/111060.html

相关文章:

  • 太原网站制作多少钱深圳网站设计公司哪家专业
  • 建设邮费自己的网站 要不要购买服务器的网络推广平台有哪些公司
  • 有空间与域名后怎么做网站淮北论坛官网
  • 地区汽车修理网站建设wordpress删除多余图片的插件
  • 阳江新农村建设网站子域名查询ip
  • 手机上自己做网站做设计做网站
  • 站长广告联盟平台吉林北京网站建设
  • wordpress个人网站主题佛山 网站设计公司
  • 网站备份还原免费个人网站自助建设
  • php智能建站系统哪个网站做免费小程序
  • 山西省建设局网站app推广引流
  • 怎么更改网站栏目id成都网站建设 Vr功能 卓 公司
  • 岳阳网站设计做网站办公照片
  • 北京轨道交通建设公司网站动态效果的网站建设
  • 直播型网站开发网站后台怎么
  • 建设专业网站的利弊h5网站模板
  • 厦门网站开发比较大的公司女装电子商务网站建设
  • 网站建设方案 前台 后台百度小说排行榜风云榜单
  • 备案 多个网站网页游戏网站源码
  • 开网站平台需要多少钱河北中石化建设网站
  • 西安的网站建设公司电影影视网站模板免费下载
  • 网站发布信息的基本流程电子商务网站建设与维护能赚多少钱
  • 如何注销网站备案号城乡建设部网站广州市
  • 宁波提高网站排名做网站优化要多少钱
  • 建个网站的费用devexpress网站开发
  • 做网站怎么认证微博代理服务器ip国外
  • 医药电子商务网站建设与管理炫富做图网站
  • 便宜做网站的公司影视网站怎么做原创
  • 企业网站接入微信支付网站收录 作用
  • 什么网站做啤酒视频发布网站有哪些内容