Spring Boot+Spring Security+MySql实现用户权限管理(3)

具体Demo

具体Demo目录:

实体类

User类为认证和授权实体类,
Role类为用户角色类,有ROLE_ADMIN和ROLE_USER
User:

package com.example.demo.entity;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * Created by linziyu on 2018/5/13.

 * 用户实体类,通过实现UserDetails接口实现认证及授权
 */
@Entity
@Table(name = "user1") //设置对应表名字
public class User implements UserDetails{

    //主键及自动增长
    @Id
    @GeneratedValue
    private  long id;
    private String name;
    private String password;

    //多对多映射,用户角色
    @ManyToMany(cascade = {CascadeType.REFRESH},fetch = FetchType.EAGER)
    private List roles;

    public long getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List getRoles() {
        return roles;
    }

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

    //获取当前用户实例的password
    @Override
    public String getPassword() {
        return this.password;
    }

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

    public User(String name, String password) {
        this.name = name;
        this.password = password;
    }

    public User() {
    }

    //根据自定义逻辑来返回用户权限,如果用户权限返回空或者和拦截路径对应权限不同,验证不通过
    @Override
    public Collection getAuthorities() {
        List authorities = new ArrayList<>();
        List roles = this.getRoles();
        for (Role role : roles) {
            authorities.add(new SimpleGrantedAuthority(role.getRolename()));
        }
        return authorities;
    }
    //获取当前用户实例的name
    @Override
    public String getUsername() {
        return this.name;
    }


    //帐号是否不过期,false则验证不通过
    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    //帐号是否不锁定,false则验证不通过
    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    //凭证是否不过期,false则验证不通过
    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    //该帐号是否启用,false则验证不通过
    @Override
    public boolean isEnabled() {
        return true;
    }
}

Role类:

package com.example.demo.entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

/**
 * Created by linziyu on 2018/5/13
 *
 * 角色实体类
 *
 */

@Entity
@Table(name = "role1")
public class Role {

    @Id
    @GeneratedValue
    private long id;

    private String rolename;

    public long getId() {
        return id;
    }

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

    public String getRolename() {
        return rolename;
    }

    public void setRolename(String rolename) {
        this.rolename = rolename;
    }
}
Dao层

使用的框架为Spring Data Jpa,所有只需继承JpaRepository即可。

配置层

安全配置:

package com.example.demo.config;

import com.example.demo.service.SecurityService;
import com.example.demo.util.MD5Util;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * Created by linziyu on 2018/5/13.
 * 安全配置类
 *
 */

@Configuration//指定为配置类
@EnableWebSecurity//指定为Spring Security配置类
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{

    @Bean
    UserDetailsService Service(){
        return new SecurityService();
    }


    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(Service()).passwordEncoder(new PasswordEncoder() {

                //用户加密配置
                @Override
                public String encode(CharSequence charSequence) {
                    return MD5Util.encode((String)charSequence);
                }

                @Override
                public boolean matches(CharSequence charSequence, String s) {
                    return s.equals(MD5Util.encode((String)charSequence));
                }
            });
    }

    /*
    通过 authorizeRequests() 定义哪些URL需要被保护、哪些不需要被保护
    通过 formLogin() 定义当需要用户登录时候,转到的登录页面。
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().
                //设置静态资源均可以访问
                antMatchers("/css/**", "/js/**","/images/**", "/webjars/**", "**/favicon.ico", "/index").permitAll()
                .anyRequest().authenticated().
                and().
                //指定登录认证的Controller
                formLogin().loginPage("/login").permitAll().
                and().
                logout().permitAll();
    }
}

视图配置类:

package com.example.demo.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

/**
 * Created by linziyu on 2018/5/13.
 * 视图跳转配置类
 *
 */

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter{
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        //设置登录处理操作
        registry.addViewController("/login").setViewName("login");
    }
}
Service层:
package com.example.demo.service;

import com.example.demo.entity.User;
import com.example.demo.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
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;

/**
 * Created by linziyu on 2018/5/13.
 * 加载用户特定数据类,为认证用户服务
 *
 */

//@Service
public class SecurityService implements UserDetailsService{

    @Autowired
    private UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        User user = userRepository.findByName(s);
        if (user == null) {
            throw new  UsernameNotFoundException("");
        }
        return user;
    }
}
package com.example.demo.service;

import com.example.demo.entity.User;
import org.springframework.data.domain.Page;

/**
 * Created by linziyu on 2018/5/13.
 * 用户类Service
 *
 */
public interface UserService {
    void save(User user);//保存用户
}
MD5用户密码加密工具类:
package com.example.demo.util;

import java.security.MessageDigest;

/**
 * Created by linziyu on 2018/5/15
 *MD5加密工具
 * .
 */
public class MD5Util {
    private static final String SALT = "tamboo";

    public static String encode(String password) {
        password = password + SALT;
        MessageDigest md5 = null;
        try {
            md5 = MessageDigest.getInstance("MD5");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        char[] charArray = password.toCharArray();
        byte[] byteArray = new byte[charArray.length];

        for (int i = 0; i < charArray.length; i++)
            byteArray[i] = (byte) charArray[i];
        byte[] md5Bytes = md5.digest(byteArray);
        StringBuffer hexValue = new StringBuffer();
        for (int i = 0; i < md5Bytes.length; i++) {
            int val = ((int) md5Bytes[i]) & 0xff;
            if (val < 16) {
                hexValue.append("0");
            }

            hexValue.append(Integer.toHexString(val));
        }
        return hexValue.toString();
    }
}
Note:

在前端使用了Thymeleaf进行渲染,特使是结合Spring Security在前端获取用户信息,如主页


<html lang="en" xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
    <meta charset="UTF-8"/>
    <title sec:authentication="name">title>
    <link rel="stylesheet" th:href="@{css/bootstrap.min.css}"/>
    <style type="text/css">
        body {
            padding-top: 50px;
        }

        .starter-template {
            padding: 40px 15px;
            text-align: center;
        }
    style>阿
head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
    <div class="container">
        <div class="navbar-header">
            <a class="navbar-brand" href="#">Spring Security演示a>
        div>
        <div id="navbar" class="collapse navbar-collapse">
            <ul class="nav navbar-nav">

            ul>
        div>
    div>
nav>
<div class="container">
    <div class="starter-template">
        <div sec:authorize="isAuthenticated()">

            <p>Hellop>
            <p>你已登录p>
            <p>登录名:<span sec:authentication="name">span>p>

            <p>拥有的角色:
                <span sec:authorize="hasRole('ROLE_ADMIN')">管理员span>
                <span sec:authorize="hasRole('ROLE_USER')">普通用户span>
            p>
        div>

        <form th:action="@{/logout}" method="post">
            <input type="submit" class="btn btn-primary" value="Logout"/>
        form>
        <div sec:authorize="hasRole('ROLE_ADMIN')">
        <form th:action="@{/toAddUser}" method="post">
            <input type="submit" class="btn btn-primary" value="Create"/>
        form>
        div>
    div>


div>
body>
html>

要注意两点:
1 依赖添加

<dependency>
    <groupId>org.thymeleaf.extrasgroupId>
    <artifactId>thymeleaf-extras-springsecurity4artifactId>
dependency>

2 版本要求
需要保持thymeleaf-extras-springsecurity4 版本与 thymeleaf相同

这样才能在前端使用类似于这种语句来获取登录用户信息

具体语法可查看:
https://github.com/thymeleaf/thymeleaf-extras-springsecurity

我的整个Demo在我的GitHub上:

https://github.com/LinZiYU1996/Spring-Boot-Spring-Security

你可能感兴趣的:(Java学习,Spring学习)