• springsecurity 授权


    springsecurity 授权就是控制访问请求,通俗说就是控制url

    具体做了些什么?

    1、认证失败会跳转到登录页面

    2、根据权限访问

    3、根据角色访问

    4、没有权限的页面展示

    授权

        //授权:针对url的设置
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                    .authorizeRequests()
                    .antMatchers("/test/**").hasAuthority("part")
                    .antMatchers("/admin/**").hasAuthority("admin")
                    .anyRequest().authenticated()
            .and().formLogin();
        }

    HttpSecurity对象的方法

    http.formLogin()//操作登录相关
    http.authorizeRequests()//操作请求相关
    http.exceptionHandling()//异常相关
    http.logout()//注销相关
    http.rememberMe()//记住我

    HttpSesurity对象方法之间可以使用.and()衔接

    http.formLogin().and().logout().and().authorizeRequests()........

    formLogin  

    .loginPage("")  //登录页面
    .failureForwardUrl("") //登录提交失败后,转发地址
    .successForwardUrl("") //登录提交成功后,转发地址
    .loginProcessingUrl("")//登录提交处理地址
    .defaultSuccessUrl("")//登录提交成功后,跳转地址
    .passwordParameter("pwd") //密码对应key
    .usernameParameter("uname") //用户名对应key
    http.formLogin()
                            //自定义登录页面
                            .loginPage("/login.html")
                            //必须和表单提交的接口一样,会去执行自定义登录逻辑
                            .loginProcessingUrl("/login")
    
                            //访问不存在的请求
                            //1、会跳转到登录页面
                            //2、登录成功,正常会跳转到提示请求不存在页面
                            // alwaysUse:true,会跳转到main.html
                            .defaultSuccessUrl("/main.html",true)
                            .defaultSuccessUrl("/toMain",true)
                            //不限制请求方式GET、POST都可以访问
                            //.defaultSuccessUrl("/main.html")
    
                            // 会报There was an unexpected error (type=Method Not Allowed, status=405).
                            //.successForwardUrl("/main.html")
                            //登录成功或转发的页面,只允许POST请求
                            .successForwardUrl("/toMain")
                            .failureForwardUrl("/toError");
                            //调用自定义Handler
    //                      .successHandler(new MyAuthenticationSuccessHandler())
    //                      .failureHandler(new MyAuthenticationFailureHandler())

    .loginProcessingUrl("/login")与form标签的action属性值一致

    <form action="/login" method="post">
        用户名:<input type="text" name="username"/> //默认登录key:username  通过usernameParameter方法修改默认值
        密 码:<input type="password" name="password"/> //默认密码key:password  通过passwordParameter方法修改默认值
        <button type="submit" >submit</button>
    </form>

    .defaultSuccessUrl("/main.html",true)、.defaultSuccessUrl("/tomain",true):不限制请求方式

        public final T defaultSuccessUrl(String defaultSuccessUrl, boolean alwaysUse) {
            SavedRequestAwareAuthenticationSuccessHandler handler = new SavedRequestAwareAuthenticationSuccessHandler();
            handler.setDefaultTargetUrl(defaultSuccessUrl);
            handler.setAlwaysUseDefaultTargetUrl(alwaysUse);
            this.defaultSuccessHandler = handler;
            return successHandler(handler);
        }

    .successForwardUrl("/toMain")、.failureForwardUrl("/toError"):只允许POST请求

        public FormLoginConfigurer<H> failureForwardUrl(String forwardUrl) {
            failureHandler(new ForwardAuthenticationFailureHandler(forwardUrl));
            return this;
        }

    .successHandler(new MyAuthenticationSuccessHandler("Url"))、.failureHandler(new MyAuthenticationFailureHandler("Url")):调用自定义Handler

    public class xxxxHandler implements AuthenticationFailureHandler {
    
        private final String forwardUrl;
    
        /**
         * @param forwardUrl
         */
        public ForwardAuthenticationFailureHandler(String forwardUrl) {
            Assert.isTrue(UrlUtils.isValidRedirectUrl(forwardUrl), () -> "'" + forwardUrl + "' is not a valid forward URL");
            this.forwardUrl = forwardUrl;
        }
    
        @Override
        public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
                AuthenticationException exception) throws IOException, ServletException {
            request.setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, exception);
            request.getRequestDispatcher(this.forwardUrl).forward(request, response);
        }
    
    }

    authorizeRequests 

    .anyRequest()//任何请求
    .antMatchers("")//指定请求  
    对请求指定访问范围
      .permitAll() // 不做任何限制连登录校验都不做
    .hasIpAddress()//指定ip访问
    .fullyAuthenticated()
    .denyAll()//拒绝所有权限/角色的访问
    .access("") //所有的访问控制方法都是基于access,permitAll()等价于access("permitAll"),hasRole("abc") 等价于 access("hasRole('abc')")
    .authenticated()//需要登录
    .hasAuthority(String)//指定权限允许访问
    .hasAnyAuthority(String ...)//包含指定权限允许访问
    .hasAnyRole(String ...)//包含指定角色允许访问
    .hasRole(String)//指定角色允许访问

    注意:hasRole、hasAnyRole方法

        private static String hasRole(String role) {
            Assert.notNull(role, "role cannot be null");
            Assert.isTrue(!role.startsWith("ROLE_"),
                    () -> "role should not start with 'ROLE_' since it is automatically inserted. Got '" + role + "'");
            return "hasRole('ROLE_" + role + "')";
        }

    角色前添加前缀,所以我们在认证设置角色时也必须添加ROLE前缀

        //授权:针对url的设置
        @Override
        protected void configure(HttpSecurity http) throws Exception {
    
                    http.authorizeRequests()
                    .antMatchers("/test/**").hasRole("guest")
                    .antMatchers("/admin/**").hasRole("admin")
                    .anyRequest().authenticated()
                    .and().formLogin();
        }

    自定义access

    @Component
    public class MyAccessImpl implements MyAccess {
        @Override
        public boolean hasPermission(HttpServletRequest request, Authentication authentication) {
            //获取用户
            Object principal =  authentication.getPrincipal();
    
            if(principal instanceof UserDetails) {
                UserDetails userDetails = (UserDetails) principal;
                Collection<? extends GrantedAuthority> authorities = userDetails.getAuthorities();
                //request.getRequestURI() => /xxx.html
                //权限是否包含/xxx.html
                //查看认证时有没有设置对应权限.authorities(AuthorityUtils.commaSeparatedStringToAuthorityList("admin,normal"));
                return authorities.contains(new SimpleGrantedAuthority(request.getRequestURI()));
            }
            return false;
        }
    }
    View Code

    调用自定义access方法

    .anyRequest().access("@myAccessImpl.hasPermission(request,authentication)");//.authenticated();

    exceptionHandling 

    .accessDeniedPage("")//指定没有权限访问页面 
        public ExceptionHandlingConfigurer<H> accessDeniedPage(String accessDeniedUrl) {
            AccessDeniedHandlerImpl accessDeniedHandler = new AccessDeniedHandlerImpl();
            accessDeniedHandler.setErrorPage(accessDeniedUrl);
            return accessDeniedHandler(accessDeniedHandler);
        }

    自定义403处理

    public class myAccessDeniedHandler implements AccessDeniedHandler {
        @Override
        public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
            response.setStatus(HttpServletResponse.SC_ACCEPTED);
    
            response.setHeader("Content-Type","application/json;charset=utf-8");
            PrintWriter writer = response.getWriter();
            writer.write("{"status":"error"}");
            writer.flush();
            writer.close();
        }
    }

    使用自定义

    http.exceptionHandling().accessDeniedHandler(new myAccessDeniedHandler());

    编辑授权(基于IP   request.getRemoteAddr())

    http.authorizeRequests()
                    .antMatchers("/login.html").permitAll()
                    .antMatchers("/add.html").hasIpAddress("127.0.0.1")
                    .anyRequest().authenticated();

    效果:localhost访问

    127.0.0.1访问

     

  • 相关阅读:
    excel表中的一列,如何去除重复项
    Notepad++ 列操作
    mysql 登陆其它服务器
    贪心算法处理背包问题
    分治法处理排序问题
    回溯法_皇后问题
    动态规划算法的java实现
    人事管理系统
    java复习笔记
    核心动画-翻页效果的实现
  • 原文地址:https://www.cnblogs.com/WarBlog/p/15133444.html
Copyright © 2020-2023  润新知