SpringBoot 集成Spring security

Spring security作为一种安全框架,使用简单,能够很轻松的集成到springboot项目中,下面讲一下如何在SpringBoot中集成Spring Security.使用gradle项目管理工具。

准备数据,

CREATE TABLE `user` (
  `uid` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) DEFAULT NULL,
  `password` varchar(255) DEFAULT NULL,
  `roles` varchar(200) DEFAULT ‘USER‘,
  PRIMARY KEY (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

insert into `user` values(0,‘admin‘,‘admin‘,‘SUPER,role‘);  //给不同个用户配置不同的权限
insert into `user` values(1,‘role‘,‘role‘,‘role‘);

1:配置buildgradle,添加spring boot插件和spring security

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath(‘org.springframework.boot:spring-boot-gradle-plugin:1.5.9.RELEASE‘)
    }
}
group "com.li"
version "1.0-SNAPSHOT"
apply plugin: "java"                           //java 插件
apply plugin: "org.springframework.boot"   //spring boot 插件
apply plugin: "io.spring.dependency-management"

apply plugin: "application"   //应用
mainClassName = "com.li.SpringBootShrioApplication"
sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web",
            "org.springframework.boot:spring-boot-starter-activemq",
            "org.springframework.boot:spring-boot-starter-test",
            "org.springframework.boot:spring-boot-starter-cache",
            "org.springframework.boot:spring-boot-devtools",
            "mysql:mysql-connector-java:5.1.35",
            ‘org.apache.commons:commons-lang3:3.4‘,
            ‘org.apache.commons:commons-pool2‘,
            "org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.0",
            ‘org.apache.logging.log4j:log4j-core:2.7‘,
            ‘org.springframework.boot:spring-boot-starter-security‘,
            ‘org.springframework.boot:spring-boot-starter-thymeleaf‘,
            ‘org.thymeleaf.extras:thymeleaf-extras-springsecurity4‘,  //thymeleaf模板,集成 springsecurity4
‘net.sourceforge.nekohtml:nekohtml‘ ) testCompile group: ‘junit‘, name: ‘junit‘, version: ‘4.12‘ }

2:配置spring boot, application.yml

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/springsecurity
    username: root
    password: 1367356
  thymeleaf:
    mode: LEGACYHTML5
    cache: false

  devtools:
    restart:
      enabled: true
server:
  port: 8081
mybatis:
  mapper-locations: classpath:mybatis/mapper/*.xml   #Mapper所在的配置文件路径,进行扫描
  config-location: classpath:mybatis/mybatis-config.xml  # mybaits-config文件

3:配置Spring Security

WebSecurityConfig.java 继承 WebSecurityConfigurerAdapter.当访问项目时,安全管理器按照配置进行拦截,验证通过才能访问Controller相应的路径。
package com.li.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
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;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Autowired
    MyUserDetailsService myUserDetailsService;

    @Bean
    public AuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
        authenticationProvider.setUserDetailsService(myUserDetailsService);
        authenticationProvider.setPasswordEncoder(this.bCryptPasswordEncoder());
        return authenticationProvider;
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(myUserDetailsService).passwordEncoder(this.bCryptPasswordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
//        String[] s=null;
        http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/user/settings").authenticated() // order matters
                .antMatchers("/", "/js/**", "/css/**","/avatar/**", "/images/**", "/fonts/**", "/bootstrap-select/**", "/bootstrap-datetimepicker/**", "/custom/**", "/daterangepicker/**", "/chartjs/**").permitAll() // these paths are configure not to require any authentication
                .antMatchers("/post/**").permitAll() // all posts are allowed to be viewed without authentication
//                .antMatchers("/user/**").permitAll() // all user profiles are allowed to be viewed without authentication
                .antMatchers("/category/**").permitAll() // all categories are allowed to be viewed without authentication
                .antMatchers("/user/registration").permitAll()
                .antMatchers("/avatar/**").permitAll() // temp
                .antMatchers("/visitor/**").permitAll() // temp
//                .antMatchers("/admin/**").hasAnyRole("SUPER","USER")
//                .antMatchers("/admin/**").
//                .antMatchers("/admin/**").hasAnyRole(s)
            .anyRequest().authenticated() // every request requires the user to be authenticated
                    .and()
            .formLogin()
                .loginPage("/user/login")
                .permitAll() // login URL can be accessed by anyone
                .and()
            .logout()
                .invalidateHttpSession(true)
                .clearAuthentication(true)
                .logoutSuccessUrl("/?logout")
                .permitAll();
    }
}

验证:对访问用户进行验证

package com.li.security;

import com.li.dao.User;
import com.li.service.UserService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

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

@Service
public class MyUserDetailsService implements UserDetailsService{

    Logger logger = LogManager.getLogger(MyUserDetailsService.class);
    @Autowired
    private UserService userService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        User user = this.userService.findUserByUserName(username);
        logger.debug(user.getUserName()+"密码"+user.getPassword());
        if(null == user) {
            throw new UsernameNotFoundException("Can‘t find user by username: " + username);
        }

        List<SimpleGrantedAuthority> grantedAuthorities = new ArrayList<>();
        // grant roles to user
        for (String role : user.getRolesSet()) {
            logger.debug(role);
            grantedAuthorities.add(new SimpleGrantedAuthority(role));  //认证
        }
//        user.setGrantedAuthorities(authorities); //用于登录时 @AuthenticationPrincipal 标签取值
        return new org.springframework.security.core.userdetails.User(user.getUserName(), user.getPassword(), grantedAuthorities);  //角色认证
    }
}

4: Controller ,Service,Dao层编写

验证通过,Controller对相应的http处理。可以在每个http上面指定相应的访问权限

package com.li.controller;

import com.li.dao.User;
import com.li.service.UserService;
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.config.ResourceNotFoundException;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.validation.Valid;
import java.util.Map;

@Controller
public class UserController {

    @Autowired
    UserService userService;

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String login() {
        System.out.println("home");
        return "forum/home";
    }

    @RequestMapping(value = "/user/login", method = RequestMethod.GET)
    public String displayLoginPage(Model model) {
        System.out.println("进入");
        model.addAttribute("title", "用户登陆");
        return "forum/user-login"; //登录界面,验证没通过。
    }

    /**
     * 用户注册
     * @param model
     * @return
     */
    @RequestMapping(value = "/user/registration", method = RequestMethod.GET)
    public String showRegistrationPage(Model model) {
        System.out.println("registrationGet");
        model.addAttribute("userDto", new User());
        return "forum/user-registration";  //注册页面
    }

    @RequestMapping(value = "/user/registration", method = RequestMethod.POST)  //提交注册
    public String registerNewUser(@ModelAttribute("userDto") User user,BindingResult bindingResult,
                                  Model model, HttpServletRequest request) {
        System.out.println("registrationPost");
        Map<String, Object> attributes = this.userService.registerUserAccount(user);
        model.addAllAttributes(attributes);
        return "forum/user-registration-result";
    }

    @PreAuthorize("hasAuthority(‘SUPER‘)")  //需要SUPER用户才能通过该路径,第一步通过配置验证,没有用户登录,将会拦截,让用户登录,登录成功,访问该路径时进行角色验证。
    @RequestMapping(value = "/admin/admin", method = RequestMethod.GET)
    public String deletePost() {
        return "admin/admin";
    }

}

Service

package com.li.service;

import com.li.dao.User;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

public interface UserService {
    public User findUserByUserName(String userName);
    public Map<String, Object> registerUserAccount(User user);
}

SeriviceImpl,对用户密码加密存储,

package com.li.service.impl;

import com.li.dao.User;
import com.li.dao.mapper.UserMapper;
import com.li.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;

@Service
public class UserServiceImpl implements UserService{

    @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    UserMapper userMapper;

    @Override
    public User findUserByUserName(String userName) {
        return userMapper.findByUserName(userName);
    }

    @Override
    public Map<String, Object> registerUserAccount(User userDto) {
        Map<String, Object> attributes = new HashMap<>();

        // save newly registered user
        User user = new User();

        user.setPassword(bCryptPasswordEncoder.encode(userDto.getPassword()));  //保存时应该将密码编码
        user.setUserName(userDto.getUserName());
//        user.activated(true);
        user.setRoles("USER");
//        user.setConfirmationToken(UUID.randomUUID().toString());

        // save new user and get number of affected row
//        logger.debug("用户注册");
        int affectedRow = userMapper.save(user);// populate attributes
        String registrationResult = affectedRow == 1 ? "success" : "failure";
        attributes.put("userRegistrationResult", registrationResult);
        return attributes;
    }
}

DaoMapper

package com.li.dao.mapper;

import com.li.dao.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

@Mapper
public interface UserMapper {
    public User findByUserName(String username);

    public int save(@Param("user") User user);
}

普通User类

package com.li.dao;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

/**
 * 实验室网站用户
 */
public class User {
    public int id;
    public String userName;
    public String password;
    public String roles;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getRoles() {
        return roles;
    }

    public void setRoles(String roles) {
        this.roles = roles;
    }

    public Set<String> getRolesSet() {   //获取用户权限
        if (null == roles) {
            return null;
        }
        return Collections.unmodifiableSet(
                new HashSet<String>(Arrays.asList(getRoles().split(","))));
    }

    public void addRole(String role) {
        String currRoles = this.getRoles();
        if (null == currRoles || this.getRoles().contains(role)) {
            return;
        }
        this.setRoles(currRoles + "," + role);
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", userName=‘" + userName + ‘\‘‘ +
                ", password=‘" + password + ‘\‘‘ +
                ", roles=‘" + roles + ‘\‘‘ +
                ‘}‘;
    }
}

5:编写项目的前台页面,不同权限的页面放到不同种类下面

原文地址:https://www.cnblogs.com/liyafei/p/9032469.html

时间: 2024-08-25 07:47:29

SpringBoot 集成Spring security的相关文章

SpringBoot集成Spring Security(4)——自定义表单登录

通过前面三篇文章,你应该大致了解了 Spring Security 的流程.你应该发现了,真正的 login 请求是由 Spring Security 帮我们处理的,那么我们如何实现自定义表单登录呢,比如添加一个验证码- 源码地址:https://github.com/jitwxs/blog_sample 文章目录 一.添加验证码 1.1 验证码 Servlet 1.2 修改 login.html 1.3 添加匿名访问 Url二.AJAX 验证三.过滤器验证 3.1 编写验证码过滤器 3.2 注

SpringBoot集成Spring Security(5)——权限控制

在第一篇中,我们说过,用户<–>角色<–>权限三层中,暂时不考虑权限,在这一篇,是时候把它完成了. 为了方便演示,这里的权限只是对角色赋予权限,也就是说同一个角色的用户,权限是一样的.当然了,你也可以精细化到为每一个用户设置权限,但是这不在本篇的探讨范围,有兴趣可以自己实验,原理都是一样的. 源码地址:https://github.com/jitwxs/blog_sample 文章目录 一.数据准备 1.1 创建 sys_permission 表 1.2 创建 POJO.Mappe

springboot集成spring security实现restful风格的登录认证 附代码

一.文章简介 本文简要介绍了spring security的基本原理和实现,并基于springboot整合了spring security实现了基于数据库管理的用户的登录和登出,登录过程实现了验证码的校验功能. 完整代码地址:https://github.com/Dreamshf/spring-security.git 二.spring security框架简介 Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架.主要包括:用户认证

SpringBoot集成Spring Security(1)——入门程序

因为项目需要,第一次接触 Spring Security,早就听闻 Spring Security 功能强大但上手困难,学习了几天出入门道,特整理这篇文章希望能让后来者少踩一点坑(本文附带实例程序,请放心食用) 本篇文章环境:SpringBoot 2.0 + Mybatis + Spring Security 5.0 源码地址:https://github.com/jitwxs/blog_sample文章目录 一.导入依赖二.创建数据库三.准备页面四.配置application.properti

Spring Boot集成Spring Security

1.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

SpringBoot2.x 集成 Spring Security

目前Web开发常用的两个安全框架:Apache Shiro 和 Spring Security,这里学习的是Spring Security,Spring Security本身是Spring社区的一个子架构,相对而言对Spring有更好的支持. Spring Security官方文档:https://docs.spring.io/spring-security/site/docs/ 安全框架基本概念: “认证” (Authentication):身份认证/登录,验证用户是不是拥有相应的身份: “授

springboot集成Spring Session

10.1 分布式集群环境下的集成(同域名.同项目) 10.1.1        创建SpringBoot的web支持项目07-springboot-session 创建项目 10.1.2        在pom.xml文件中添加依赖 <!-- 配置spring session的依赖 --> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-

SpringMVC 3.2集成Spring Security 3.2集成mybaties

目录结构如下 1.pom.xml <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/maven-v4_0_0.xsd">

SpringBoot非官方教程 | 第十三篇:springboot集成spring cache

转载请标明出处: http://blog.csdn.net/forezp/article/details/71023614 本文出自方志朋的博客 本文介绍如何在springboot中使用默认的spring cache, 声明式缓存 Spring 定义 CacheManager 和 Cache 接口用来统一不同的缓存技术.例如 JCache. EhCache. Hazelcast. Guava. Redis 等.在使用 Spring 集成 Cache 的时候,我们需要注册实现的 CacheMana