SpringBoot精选Spring Boot

SpringBoot 全家桶 | SpringSecurity实

2020-09-09  本文已影响0人  码农StayUp

本文源码:Gitee·点这里

介绍

Spring Security 是一个功能强大且高度可定制的身份证认证和访问控制框架。其最重要的两部分是认证(Authentication)和授权(Authorization)。

本实例使用框架:

Spring Security 后端实例

引入包

我们引入spring-boot-starter-security包,同时为完成实例引入了其他的包,这里不多做介绍

<dependencies>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <dependency>
        <groupId>org.thymeleaf.extras</groupId>
        <artifactId>thymeleaf-extras-springsecurity5</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>

</dependencies>

配置数据源

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/springboot-security?charset=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password: root
  jpa:
    show-sql: true
    hibernate:
      ddl-auto: update

Security配置文件

我们创建一个Security的配置类,并继承WebSecurityConfigurerAdapter类,加上@EnableWebSecurity注解,表示启用Security,下面看详细代码

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Resource
    private UserDao userDao;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
              .antMatchers("/css/**", "/", "/index", "/loginPage").permitAll() // 无需认证
                .anyRequest().authenticated() // 其他请求都需要认证
        ;

        http.formLogin() // 开启登录,如果没有权限,就会跳转到登录页
                .loginPage("/loginPage") // 自定义登录页,默认/login(get请求)
                .loginProcessingUrl("/login") // 登录处理地址,默认/login(post请求)
                .usernameParameter("inputEmail") // 自定义username属性名,默认username
                .passwordParameter("inputPassword") // 自定义password属性名,默认password
        ;

        http.rememberMe() // 开启记住我
                .rememberMeParameter("rememberMe") // 自定义rememberMe属性名
        ;

        http.logout() // 开启注销
                .logoutUrl("/logout") // 注销处理路径,默认/logout
                .logoutSuccessUrl("/") // 注销成功后跳转路径
        ;

        http.csrf().disable(); // 禁止csrf
    }

    @Bean
    public UserDetailsService userDetailsService() {
        return username -> {
            xyz.zyl2020.security.entity.User user = userDao.findByUsernameOrEmail(username, username);
            if (user == null) {
                throw new UsernameNotFoundException("账号或密码错误!");
            }
            String[] roleCodeArray = user.getRoles().stream().map(Role::getCode).toArray(String[]::new);

            return User.withUsername(user.getUsername())
                    .password(user.getPassword())
                    .roles(roleCodeArray)
                    .build();
        };
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
2020-08-24 22:03:20.014 ERROR 4692 --- [nio-8080-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception

java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
    ......

Controller配置

@Controller
public class RouteController {

    @RequestMapping({"/", "/index"})
    public String index() {
        return "index";
    }

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

    @GetMapping("/currentUser")
    public String getUsername() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        Object principal = authentication.getPrincipal();
        if (principal == null) {
            return null;
        }
        UserDetails userDetails = (UserDetails) principal;
        return userDetails.getUsername();
    }
}

Service层、Dao层、和实体类查阅下面的【完整代码】吧,另外用户、角色、及其关系的初始化,在test代码中

Spring Security 前端使用thymeleaf

登录页 - 表单的使用

<form class="form-signin" action="/login" method="post">
    <h1 class="h3 mb-3 font-weight-normal">Please sign in</h1>
    <label for="inputEmail" class="sr-only">Email address</label>
    <input type="email" id="inputEmail" name="inputEmail" class="form-control" placeholder="Email address" required autofocus>
    <label for="inputPassword" class="sr-only">Password</label>
    <input type="password" id="inputPassword" name="inputPassword" class="form-control" placeholder="Password" required>
    <div class="checkbox mb-3">
        <label>
            <input type="checkbox" name="rememberMe"> Remember me
        </label>
    </div>
    <button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
    <p class="mt-5 mb-3 text-muted">&copy; 2017-2020</p>
</form>

做好以前配置,提交表单后会将用户名、密码、记住我信息提交致后台进行认证授权

主页 - Thymeleaf与Security的集成

thymeleaf与Security集成,主要使用引入的thymeleaf-extras-springsecurity5

<!doctype html>
<html lang="en" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
    // 代码省略...
</head>
<body>
<div class="d-flex flex-column flex-md-row align-items-center p-3 px-md-4 mb-3 bg-white border-bottom shadow-sm">
    <h5 class="my-0 mr-md-auto font-weight-normal">Welcome!</h5>
    <nav class="my-2 my-md-0 mr-md-3">
        <div sec:authorize="!isAuthenticated()">
            <a class="btn btn-outline-primary" href="/loginPage">Login</a>
        </div>
        <div sec:authorize="isAuthenticated()">
            <span sec:authentication="name"></span>
            <a class="btn btn-outline-primary" href="/logout">Logout</a>
        </div>
    </nav>

</div>

<div class="pricing-header px-3 py-3 pt-md-5 pb-md-4 mx-auto text-center">
    <h1 class="display-4">Pricing</h1>
    <p class="lead">Quickly build an effective pricing table for your potential customers with this Bootstrap example.
        It’s built with default Bootstrap components and utilities with little customization.</p>
</div>

<div class="container">
    <div class="card-deck mb-3 text-center">
        <div class="card mb-4 shadow-sm" sec:authorize="hasAnyRole('FREE')">
            <div class="card-header">
                <h4 class="my-0 font-weight-normal">Free</h4>
            </div>
            <div class="card-body">
                <h1 class="card-title pricing-card-title">$0 <small class="text-muted">/ mo</small></h1>
                <ul class="list-unstyled mt-3 mb-4">
                    <li>10 users included</li>
                    <li>2 GB of storage</li>
                    <li>Email support</li>
                    <li>Help center access</li>
                </ul>
                <a class="btn btn-lg btn-block btn-primary" href="#">Get started</a>
            </div>
        </div>
        <div class="card mb-4 shadow-sm" sec:authorize="hasAnyRole('PRO')">
            <div class="card-header">
                <h4 class="my-0 font-weight-normal">Pro</h4>
            </div>
            <div class="card-body">
                <h1 class="card-title pricing-card-title">$15 <small class="text-muted">/ mo</small></h1>
                <ul class="list-unstyled mt-3 mb-4">
                    <li>20 users included</li>
                    <li>10 GB of storage</li>
                    <li>Priority email support</li>
                    <li>Help center access</li>
                </ul>
                <a class="btn btn-lg btn-block btn-primary">Get started</a>
            </div>
        </div>
        <div class="card mb-4 shadow-sm" sec:authorize="hasAnyRole('ENT')">
            <div class="card-header">
                <h4 class="my-0 font-weight-normal">Enterprise</h4>
            </div>
            <div class="card-body">
                <h1 class="card-title pricing-card-title">$29 <small class="text-muted">/ mo</small></h1>
                <ul class="list-unstyled mt-3 mb-4">
                    <li>30 users included</li>
                    <li>15 GB of storage</li>
                    <li>Phone and email support</li>
                    <li>Help center access</li>
                </ul>
                <a class="btn btn-lg btn-block btn-primary">Get started</a>
            </div>
        </div>
    </div>

</div>
</body>
</html>

更多功能请参照官网

参考

  1. Spring Security
  2. thymeleaf-extras-springsecurity
  3. Thymeleaf + Spring Security integration basics
  4. Bootstrap4

完整代码

springboot-security

登录前.png
登录页.png
登录后.png 福利.jpg
上一篇下一篇

猜你喜欢

热点阅读