Spring Security 简单使用

前提是你 提交于 2020-03-26 18:59:46

3 月,跳不动了?>>>

社区链接:http://www.spring4all.com/article/428

Spring Security 入门系列《Spring Security 动态权限修改》存在问题。 以下是改正后的代码。

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.springframework</groupId>
    <artifactId>gs-securing-web</artifactId>
    <version>0.1.0</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.7.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
            </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity4</artifactId>
        </dependency>

        <!-- bootstrap and jquery -->
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId>
            <version>3.3.7</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>3.2.1</version>
        </dependency>

        <!-- testing -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Camden.SR5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <properties>
        <java.version>1.8</java.version>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-releases</id>
            <name>Spring Releases</name>
            <url>https://repo.spring.io/libs-release</url>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-releases</id>
            <name>Spring Releases</name>
            <url>https://repo.spring.io/libs-release</url>
        </pluginRepository>
    </pluginRepositories>
</project>

启动类

package top.heliming.shiro.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;

@SpringBootApplication
@EnableGlobalMethodSecurity(prePostEnabled = true)//打开权限验证
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

配置类

package top.heliming.shiro.demo.config;

/**
 * description:
 *
 * @author: he QQ:       905845006
 * @email: 905845006@qq.com
 * @date: 2020/3/26    5:04 PM
 */
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

// 使用注解方式配置SpringSecurity记住我配置时,开启此注解
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring()
                .antMatchers(
                        "/js/**",
                        "/css/**",
                        "/img/**",
                        "/webjars/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
                .logout()
                .invalidateHttpSession(true)
                .clearAuthentication(true)
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                .logoutSuccessUrl("/login?logout")
                .permitAll()
                .and()
                .rememberMe()
                .key("unique-and-secret")
                .rememberMeCookieName("remember-me-cookie-name")
                .tokenValiditySeconds(24 * 60 * 60);
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");

        //创建ADMIN角色
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                .withUser("vip").password(new BCryptPasswordEncoder()
                .encode("123456")).roles("VIP");
        //创建USER角色
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                .withUser("demo").password(new BCryptPasswordEncoder()
                .encode("demo")).roles("USER");

    }



}


控制类

package top.heliming.shiro.demo.controller;

/**
 * description:
 *
 * @author: he QQ:       905845006
 * @email: 905845006@qq.com
 * @date: 2020/3/26    5:08 PM
 */

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.ArrayList;
import java.util.List;

@Controller
public class HomeController {

    @GetMapping("/")
    public String greeting(){
        return "index";
    }

    @GetMapping("/login")
    public String login() {
        return "login";
    }

    @GetMapping("/vip/test")
    //验证不同角色的登录权限
    @PreAuthorize("hasRole('ROLE_VIP')")//只有是ADMIN权限的才可以访问该地址,使用该权限需要头部引入打开权限验证注解
    @ResponseBody
    public String vipPath() {
        return "仅 ROLE_VIP 可看";
    }

    @GetMapping("/vip")
    @ResponseBody
    public boolean updateToVIP() {
        // 得到当前的认证信息
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        //  生成当前的所有授权
        List<GrantedAuthority> updatedAuthorities = new ArrayList<>(auth.getAuthorities());
        // 添加 ROLE_VIP 授权
        updatedAuthorities.add(new SimpleGrantedAuthority("ROLE_VIP"));
        // 生成新的认证信息
        Authentication newAuth = new UsernamePasswordAuthenticationToken(auth.getPrincipal(), auth.getCredentials(), updatedAuthorities);
        // 重置认证信息
        SecurityContextHolder.getContext().setAuthentication(newAuth);
        return true;
    }
}


静态文件

login.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
    <meta name="viewport" content="width=device-width, initial-scale=1"/>

    <link rel="stylesheet" type="text/css" th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap.min.css}"/>
    <link rel="stylesheet" type="text/css" th:href="@{/css/main.css}"/>

    <title>Login</title>
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-4 col-md-offset-4">
            <div class="panel panel-default">
                <div class="panel-body">
                    <div class="text-center">
                        <h3><i class="glyphicon glyphicon-lock" style="font-size:2em;"></i></h3>
                        <h2 class="text-center">Login</h2>
                        <div class="panel-body">

                            <div th:if="${param.error}">
                                <div class="alert alert-danger">
                                    Invalid username or password.
                                </div>
                            </div>
                            <div th:if="${param.logout}">
                                <div class="alert alert-info">
                                    You have been logged out.
                                </div>
                            </div>

                            <form th:action="@{/login}" method="post">
                                <div class="form-group">
                                    <div class="input-group">
                                        <span class="input-group-addon">@</span>
                                        <input id="username"
                                               name="username"
                                               autofocus="autofocus"
                                               class="form-control"
                                               placeholder="Username"/>
                                    </div>
                                </div>
                                <div class="form-group">
                                    <div class="input-group">
                                        <span class="input-group-addon">
                                            <i class="glyphicon glyphicon-lock"></i>
                                        </span>
                                        <input id="password"
                                               name="password"
                                               class="form-control"
                                               placeholder="Password"
                                               type="password"/>
                                    </div>
                                </div>
                                <div class="form-group">
                                    <label>
                                        <input id="remember-me"
                                               name="remember-me"
                                               type="checkbox"/> Remember me
                                    </label>
                                </div>
                                <div class="form-group">
                                    <button type="submit" class="btn btn-success btn-block">Login</button>
                                </div>
                            </form>

                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<script type="text/javascript" th:src="@{/webjars/jquery/3.2.1/jquery.min.js/}"></script>
<script type="text/javascript" th:src="@{/webjars/bootstrap/3.3.7/js/bootstrap.min.js}"></script>

</body>
</html>

index.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.w3.org/1999/xhtml">
    <head>
        <meta charset="utf-8"/>
        <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
        <meta name="viewport" content="width=device-width, initial-scale=1"/>

        <link rel="stylesheet" type="text/css" th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap.min.css}"/>
        <link rel="stylesheet" type="text/css" th:href="@{/css/main.css}"/>

        <title>Registration</title>
    </head>
    <body>
        <div class="container">
            <h1>Spring Security Remember Me Hashing Configuration Example</h1>

            <div sec:authorize="isRememberMe()">
                The user: <span sec:authentication="name"></span> is logged in by "Remember Me Cookies".
            </div>

            <div sec:authorize="isFullyAuthenticated()">
                The user: <span sec:authentication="name"></span> is logged in by "Username / Password".
            </div>

        </div>
        <footer>
            <div class="container">
                <p>
                    &copy; Memorynotfound.com
                    <span sec:authorize="isAuthenticated()" style="display: inline-block;">
                        | Logged user: <span sec:authentication="name"></span> |
                        Roles: <span sec:authentication="principal.authorities"></span> |
                        <a th:href="@{/logout}">Sign Out</a>
                    </span>
                </p>
            </div>
        </footer>

        <script type="text/javascript" th:src="@{/webjars/jquery/3.2.1/jquery.min.js/}"></script>
        <script type="text/javascript" th:src="@{/webjars/bootstrap/3.3.7/js/bootstrap.min.js}"></script>

    </body>
</html>

测试

访问:http://localhost:8080

输入用户:demo密码:demo

登录到主页

访问:http://localhost:8080/vip/test     提示403没有权限
访问:http://localhost:8080/vip 	增加角色权限
访问:http://localhost:8080/vip/test	返回 仅 ROLE_VIP 可看

修改后的地方:

  1. 启动类开启

     @EnableGlobalMethodSecurity(prePostEnabled = true)//打开权限验证
    
  2. 配置类

     添加用户
     //        auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
    
     //创建ADMIN角色
     auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
             .withUser("vip").password(new BCryptPasswordEncoder()
             .encode("123456")).roles("VIP");
     //创建USER角色
     auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
             .withUser("demo").password(new BCryptPasswordEncoder()
             .encode("demo")).roles("USER");
    
  3. 控制类

     1. vipPath()方法修改注解@Secured("ROLE_VIP")  为
     //验证不同角色的登录权限
     @PreAuthorize("hasRole('ROLE_VIP')")//只有是ADMIN权限的才可以访问该地址,使用该权限需要头部引入打开权限验证注解
     增加注解@ResponseBody
    
     2. updateToVIP()增加注解@ResponseBody
    
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!