zoukankan      html  css  js  c++  java
  • SpringSecurity

    比较有名的安全框架Shiro和SpringSecurity

    实战

    环境准备

    @Controller
    public class RouterController {
        @RequestMapping({"/","/index"})
        public String index(){
            return "index";
        }
        @RequestMapping("/toLogin")
        public String toLogin(){
            return "views/Login";
        }
        @RequestMapping("/level1/{id}")
        public String level1(@PathVariable("id") int id){
            return "views/level1/"+id;
        }
        @RequestMapping("/level2/{id}")
        public String level2(@PathVariable("id") int id){
            return "views/level2/"+id;
        }
        @RequestMapping("/level3/{id}")
        public String level3(@PathVariable("id") int id){
            return "views/level3/"+id;
        }
    }

    SpringSecurity是针对Spring项目的安全框架,自需要引入spring-boot-starter-security模块,在进行少量配置就可以实现强大的安全管理

    3个类:

    • WebSecurityConfigureAdapter:自定义Security策略
    • AuthenicationManagerBuilder:自定义认证策略
    • @EnableWebSecurity:开启WebSecurity模式

    SpringSecruity的两个主要目标就是认证和授权

    认证和授权

    导入SpringSecurity模块

     <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
     </dependency>

    编写SpringSecurity的配置类

    @EnableWebSecurity
    //开启WbSecurity模式
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            // 定制请求的授权规则
            // 首页所有人可以访问
            http.authorizeRequests().antMatchers("/").permitAll()
                    .antMatchers("/level1/**").hasRole("vip1")
                    .antMatchers("/level2/**").hasRole("vip2")
                    .antMatchers("/level3/**").hasRole("vip3");
            //会跳转到默认的登录页面
    http.formLogin(); } }

    除了首页,其它页面都不可以访问,因为没有登录

    定义认证规则

     //定以认证规则
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()).withUser("dengwenxiong1").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2").and().withUser("dengwenxiong2").password(new BCryptPasswordEncoder().encode("123456")).roles("vip3","vip2");
        }

    密码必须进行加密,否则无法登录;SpringSecurity官方推荐使用bcrypt加密方式,登录后就能访问到对应页面

    权限控制和注销

    注销登录:

    @Override
    protected void configure(HttpSecurity http) throws Exception {
         //....
        //开启自动配置的注销的功能
        // /logout 注销请求
        http.logout();
    }

    注销成功后默认跳转到登录页面,可以使用logoutSuccessUrl()来指定注销后跳转到的页面

    http.logout().logoutSuccessUrl("/");

    需求:用户没有登录只显示登录按钮,登录后显示用户信息与注销按钮,并且显示用户拥有的功能,用户没拥有的功能不会显示

    结合thymeleaf来实现,sec: authorize="isAuthenticated()"是否认证登录来显示不同的页面

    导入依赖

     <dependency>
                <groupId>org.thymeleaf.extras</groupId>
                <artifactId>thymeleaf-extras-springsecurity5</artifactId>
    </dependency>

    用户登录与未登录显示

    <div class="right menu">
        <!--如果未登录-->
        <div sec:authorize="!isAuthenticated()">
            <a class="item" th:href="@{/login}">
                <i class="address card icon"></i> 登录
            </a>
        </div>
        <!--如果已登录-->
        <div sec:authorize="isAuthenticated()">
            <a class="item">
                <i class="address card icon"></i>
                用户名: <span sec:authentication="principal.username">
    </span>
                角色:<span sec:authentication="principal.authorities">
    </span>
            </a>
        </div>
        <div sec:authorize="isAuthenticated()">
            <a class="item" th:href="@{/logout}">
                <i class="address card icon"></i> 注销
            </a>
        </div>
    </div>

    用户功能块显示sec: authorize="hasRole()"

    <div class="column" sec:authorize="hasRole('vip1')">
        <div class="ui raised segment">
            <div class="ui">
                <div class="content">
                    <h5 class="content">Level 1</h5>
                    <hr>
                    <div><a th:href="@{/level1/1}"><i class="bullhorn icon">
                    </i> Level-1-1</a></div>
                    <div><a th:href="@{/level1/2}"><i class="bullhorn icon">
                    </i> Level-1-2</a></div>
                    <div><a th:href="@{/level1/3}"><i class="bullhorn icon">
                    </i> Level-1-3</a></div>
                </div>
            </div>
        </div>
    </div>
    <div class="column" sec:authorize="hasRole('vip2')">
        <div class="ui raised segment">
            <div class="ui">
                <div class="content">
                    <h5 class="content">Level 2</h5>
                    <hr>
                    <div><a th:href="@{/level2/1}"><i class="bullhorn icon">
                    </i> Level-2-1</a></div>
                    <div><a th:href="@{/level2/2}"><i class="bullhorn icon">
                    </i> Level-2-2</a></div>
                    <div><a th:href="@{/level2/3}"><i class="bullhorn icon">
                    </i> Level-2-3</a></div>
                </div>
            </div>
        </div>
    </div>
    <div class="column" sec:authorize="hasRole('vip3')">
        <div class="ui raised segment">
            <div class="ui">
                <div class="content">
                    <h5 class="content">Level 3</h5>
                    <hr>
                    <div><a th:href="@{/level3/1}"><i class="bullhorn icon">
                    </i> Level-3-1</a></div>
                    <div><a th:href="@{/level3/2}"><i class="bullhorn icon">
                    </i> Level-3-2</a></div>
                    <div><a th:href="@{/level3/3}"><i class="bullhorn icon">
                    </i> Level-3-3</a></div>
                </div>
            </div>
        </div>
    </div>

    记住账号密码功能

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //。。。。。。。。。。。
        //记住我
        http.rememberMe();
    }

    在登录成功时将cookie发送给浏览器保存,再登录时会带上这个cookie,通过了检查就可以免登录。再注销时会删除该cookie

    定制登录页

    SpringSecurity会提供一个默认的登录页面,我们也可以自定义登录页面,跳转到自定义的登录页面

    http.formLogin().loginPage("/toLogin");

    还要配置登录信息发送到哪里(/login)

    <form th:action="@{/login}" method="post">
        <div class="field">
            <label>Username</label>
            <div class="ui left icon input">
                <input type="text" placeholder="Username" name="username">
                <i class="user icon"></i>
            </div>
        </div>
        <div class="field">
            <label>Password</label>
            <div class="ui left icon input">
                <input type="password" name="password">
                <i class="lock icon"></i>
            </div>
        </div>
        <input type="submit" class="ui blue submit button"/>
    </form>

    进行验证处理并增加记住我验证

    http.formLogin().usernameParameter("username").passwordParameter("password").loginPage("/toLogin").loginProcessingUrl("/login");
    http.rememberMe().rememberMeParameter("remember");
  • 相关阅读:
    HTTP协议
    JavaScript学习(一)
    Cookie&Session
    注解初学
    反射初学
    XML
    Web概念
    Response对象
    Servlet
    LeetCode Notes_#617 Merge Two Binary Trees
  • 原文地址:https://www.cnblogs.com/dwx-study/p/14725812.html
Copyright © 2011-2022 走看看