spring security 使用众多的拦截器实现权限控制的, 其核心有2个重要的概念: 认证(Authentication) 和授权 (Authorization)), 认证就是确认用户可以访问当前系统, 授权即确定用户有相应的权限,

    现在先大概过一遍整个流程,用户登陆,会被AuthenticationProcessingFilter拦截,调用AuthenticationManager的实现,而且AuthenticationManager会调用ProviderManager来获取用户验证信息(不同的Provider调用的服务不同,因为这些信息可以是在数据库上,可以是在LDAP服务器上,可以是xml配置文件上等),如果验证通过后会将用户的权限信息封装一个User放到spring的全局缓存SecurityContextHolder中,以备后面访问资源时使用。
访问资源(即授权管理),访问url时,会通过AbstractSecurityInterceptor拦截器拦截,其中会调用FilterInvocationSecurityMetadataSource的方法来获取被拦截url所需的全部权限,在调用授权管理器AccessDecisionManager,这个授权管理器会通过spring的全局缓存SecurityContextHolder获取用户的权限信息,还会获取被拦截的url和被拦截url所需的全部权限,然后根据所配的策略(有:一票决定,一票否定,少数服从多数等),如果权限足够,则返回,权限不够则报错并调用权限不足页面 ( http://blog.csdn.net/u012367513/article/details/38866465)
 
  本例的用户和角色信息存储在mysql, 使用mybatis进行查询:http://www.cnblogs.com/wenbronk/p/7357996.html

项目 使用 idea + gradle

dependencies {
compile("org.springframework.boot:spring-boot-devtools")
compile("org.springframework.boot:spring-boot-starter")
compile("org.springframework.boot:spring-boot-starter-web")
compile("org.springframework.boot:spring-boot-starter-log4j2")
compile("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml")
compile("org.codehaus.groovy:groovy-all:2.4.12") compile("org.springframework.boot:spring-boot-starter-security")
compile("org.springframework.boot:spring-boot-starter-thymeleaf")
compile("org.thymeleaf.extras:thymeleaf-extras-springsecurity4") compile ("mysql:mysql-connector-java")
compile 'com.alibaba:druid-spring-boot-starter:1.1.2'
compile ("org.mybatis.spring.boot:mybatis-spring-boot-starter:1.1.1") compile 'com.alibaba:fastjson:1.1.15'
compile 'javax.inject:javax.inject:1'
testCompile group: 'junit', name: 'junit', version: '4.12'
testCompile("org.springframework.boot:spring-boot-starter-test") }

1, 导入基础数据, 调试mybatis

1) , 建表

/*
Navicat MySQL Data Transfer
Source Server : 本地
Source Host : localhost:3306
Source Database : test
Target Server Type : MYSQL
Date: 2017-8-14 22:17:33
*/ SET FOREIGN_KEY_CHECKS=; -- ----------------------------
-- Table structure for `sys_user`
-- ----------------------------
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user` (
`id` INT () NOT NULL AUTO_INCREMENT COMMENT '主键id',
`username` varchar() DEFAULT NULL COMMENT '用户名',
`password` varchar() DEFAULT NULL COMMENT '密码',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT= DEFAULT CHARSET=utf8; -- ----------------------------
-- Table structure for `sys_role`
-- ----------------------------
DROP TABLE IF EXISTS `sys_role`;
CREATE TABLE `sys_role` (
`id` INT () NOT NULL AUTO_INCREMENT COMMENT '主键id',
`name` varchar() DEFAULT NULL COMMENT '用户名',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT= DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for `sys_role_user`
-- ----------------------------
DROP TABLE IF EXISTS `sys_role_user`;
CREATE TABLE `sys_role_user` (
`id` bigint() NOT NULL AUTO_INCREMENT COMMENT '主键id',
`sys_user_id` INT() NOT NULL COMMENT 'user_id',
`sys_role_id` INT() NOT NULL COMMENT 'role_id',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT= DEFAULT CHARSET=utf8; ALTER TABLE sys_role_user ADD CONSTRAINT sys_FK1 FOREIGN KEY(sys_user_id) REFERENCES sys_user(id);
ALTER TABLE sys_role_user ADD CONSTRAINT role_FK2 FOREIGN KEY(sys_role_id) REFERENCES sys_role(id);

导入数据

insert into SYS_USER (id,username, password) values (,'vini', '');
insert into SYS_USER (id,username, password) values (,'bronk', ''); insert into SYS_ROLE(id,name) values(,'ROLE_ADMIN');
insert into SYS_ROLE(id,name) values(,'ROLE_USER'); insert into SYS_ROLE_USER(SYS_USER_ID,sys_role_id) values(,);
insert into SYS_ROLE_USER(SYS_USER_ID,sys_role_id) values(,);

在 application.yml中配置如下, 可以在启动程序时自动执行

spring:
datasource:
url: jdbc:mysql://localhost:3306/springboot
username: root
password: root
# type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
  # 一下2行
schema: classpath:security.sql
data: classpath:security-data.sql

2), mapper映射

package com.wenbronk.security.mapper

import com.wenbronk.security.entity.SysUser

/**
* Created by wenbronk on 2017/8/14.
*/
interface SysUserMapper {
SysUser findByUserName(String username)
}

在 resources/mybatis/mapper中添加:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.wenbronk.security.mapper.SysUserMapper"> <resultMap id="sys_user_map" type="SysUser">
<id property="id" column="id" />
<result property="username" column="username" />
<result property="password" column="password" />
<collection property="roles" ofType="SysRole">
<result column="name" property="name" />
</collection> </resultMap> <select id="findByUserName" parameterType="string" resultMap="sys_user_map">
select u.id, u.username, u.password, r.name
from sys_user u
LEFT JOIN sys_role_user s on u.id = s.sys_user_id
LEFT JOIN sys_role r on r.id = s.sys_role_id
WHERE username = #{username}
</select>
</mapper>

在application.yml中配置

mybatis:
config-location: classpath:mybatis/SqlMapConfig.xml
mapper-locations: classpath:mybatis/mapper/*.xml

在main方法上添加mapper扫描:

@SpringBootApplication
@MapperScan("com.wenbronk.security.mapper")
public class SecurityApplication {
public static void main(String[] args) {
SpringApplication.run(SecurityApplication.class);
}
}

3), 实体类

class Msg {
String title
String content
String etraInfo Msg() {
} Msg(String title, String content, String etraInfo) {
this.title = title
this.content = content
this.etraInfo = etraInfo
}
}

SysUser.groovy

package com.wenbronk.security.entity

/**
* Created by wenbronk on 2017/8/14.
*/
class SysUser {
int id
def username
def password
List<SysRole> roles @Override
public String toString() {
return "SysUser{" +
"id=" + id +
", username=" + username +
", password=" + password +
", roles=" + roles +
'}';
}
}

SysRole.groovy

package com.wenbronk.security.entity

/**
* Created by wenbronk on 2017/8/14.
*/
class SysUser {
int id
def username
def password
List<SysRole> roles @Override
public String toString() {
return "SysUser{" +
"id=" + id +
", username=" + username +
", password=" + password +
", roles=" + roles +
'}';
}
}

4) , 测试mybatis

    @Test
void test2() {
def name = sysUserMapper.findByUserName('vini')
println name
}

2, security相关配置

1), CustomerUserService.groovy
package com.wenbronk.security.security.service

import com.wenbronk.security.entity.SysRole
import com.wenbronk.security.entity.SysUser
import com.wenbronk.security.mapper.SysUserMapper
import org.springframework.security.core.authority.SimpleGrantedAuthority
import org.springframework.security.core.userdetails.User
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 javax.inject.Inject
/**
* Created by wenbronk on 2017/8/15.
*/
@Service
class CustomUserService implements UserDetailsService { @Inject
SysUserMapper sysUserMapper; @Override
UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
def sysUser = sysUserMapper.findByUserName(s) as SysUser
assert sysUser != null
List<SimpleGrantedAuthority> authorities = new ArrayList<>()
for(SysRole role : sysUser.getRoles()) {
authorities.add(new SimpleGrantedAuthority(role.getName()))
println role.getName();
}
return new User(sysUser.getUsername(), sysUser.getPassword(), authorities)
}
}

2), WebSecurityConfig.groovy

package com.wenbronk.security.security.config

import com.wenbronk.security.security.service.CustomUserService
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 javax.inject.Inject
/**
* Created by wenbronk on 2017/8/15.
*/
@Configuration
@EnableWebSecurity
class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Inject
CustomUserService customUserService; @Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserService);
} @Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated() // 任何请求都拦截
.and()
.formLogin()
.loginPage("/login")
.failureUrl("/login?error")
.permitAll() // 登陆后可访问任意页面
.and()
.logout().permitAll(); // 注销后任意访问 }
}

3, 页面

1), 页面转向设置

package com.wenbronk.security.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 wenbronk on 2017/8/15.
*/
@Configuration
class WebMvcConfig extends WebMvcConfigurerAdapter{ @Override
void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login")
}
}

controller.groovy

package com.wenbronk.security.controller

import com.wenbronk.security.entity.Msg
import org.springframework.stereotype.Controller
import org.springframework.ui.Model
import org.springframework.web.bind.annotation.RequestMapping
/**
* Created by wenbronk on 2017/8/14.
*/
@Controller
class SecurityController { @RequestMapping("/")
def index(Model model) {
def msg = new Msg("测试标题", "测试内容", "额外信息, 只对管理员显示")
model.addAttribute("msg", msg);
"home"
} }

在resources下放入静态资源, bootstramp.min.css, 以及thymeleaf页面

login.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta content="text/html;charset=UTF-8"/>
<title>登录页面</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">
<li><a th:href="@{/}"> 首页 </a></li> </ul>
</div><!--/.nav-collapse -->
</div>
</nav>
<div class="container"> <div class="starter-template">
<p th:if="${param.logout}" class="bg-warning">已成功注销</p><!-- -->
<p th:if="${param.error}" class="bg-danger">有错误,请重试</p> <!-- -->
<h2>使用账号密码登录</h2>
<form name="form" th:action="@{/login}" action="/login" method="POST"> <!-- -->
<div class="form-group">
<label for="username">账号</label>
<input type="text" class="form-control" name="username" value="" placeholder="账号" />
</div>
<div class="form-group">
<label for="password">密码</label>
<input type="password" class="form-control" name="password" placeholder="密码" />
</div>
<input type="submit" id="login" value="Login" class="btn btn-primary" />
</form>
</div>
</div>
</body>
</html>

home.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
<meta content="text/html;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">
<li><a th:href="@{/}"> 首页 </a></li>
</ul>
</div><!--/.nav-collapse -->
</div>
</nav> <div class="container"> <div class="starter-template">
<h1 th:text="${msg.title}"></h1> <p class="bg-primary" th:text="${msg.content}"></p> <div sec:authorize="hasRole('ROLE_ADMIN')"> <!-- 用户类型为ROLE_ADMIN 显示 -->
<p class="bg-info" th:text="${msg.etraInfo}"></p>
</div> <div sec:authorize="hasRole('ROLE_USER')"> <!-- 用户类型为 ROLE_USER 显示 -->
<p class="bg-info">无更多信息显示</p>
</div> <form th:action="@{/logout}" method="post">
<input type="submit" class="btn btn-primary" value="注销"/>
</form>
</div> </div>
</body> </html>
 
 参见: JavaEE颠覆者, springboot实战
  

springboot-28-security(一)用户角色控制的更多相关文章

  1. Vue-Access-Control:前端用户权限控制解决方案

    原文地址:http://refined-x.com/2017/11/28/Vue2.0用户权限控制解决方案/ Vue-Access-Control是一套基于Vue/Vue-Router/axios 实 ...

  2. springboot+mybatis+SpringSecurity 实现用户角色数据库管理(一)

    本文使用springboot+mybatis+SpringSecurity 实现用户权限数据库管理 实现用户和角色用数据库存储,而资源(url)和权限的对应采用硬编码配置. 也就是角色可以访问的权限通 ...

  3. Spring Security 整合freemaker 实现简单登录和角色控制

    Spring Security 整合freemaker 实现简单登录和角色控制     写这篇文章是因为我做了一个电商网站项目,近期刚加上权限控制.整个过程很简单,在此给大家梳理一下,也算是自己对知识 ...

  4. 【shiro】2.spring整合shiro,注解控制shiro用户/角色/权限And/OR,没有权限跳转到固定页面

    这几天粗浅的把shiro整合到spring中,并且注解控制shiro用户/角色/权限And/OR 步骤: 1.首先maven搭建web项目 2.创建数据库 user/role/authority 其中 ...

  5. SpringSecurity 自定义用户 角色 资源权限控制

    SpringSecurity 自定义用户 角色 资源权限控制 package com.joyen.learning.security; import java.sql.ResultSet; impor ...

  6. RabbitMQ用户角色及权限控制

    RabbitMQ的用户角色分类:none.management.policymaker.monitoring.administrator RabbitMQ各类角色描述:none不能访问 managem ...

  7. RabbitMQ用户角色及权限控制(转)

    转载至:https://blog.csdn.net/awhip9/article/details/72123257 2017年05月15日 10:39:26 awhip9 阅读数:3538   ### ...

  8. RabbitMQ用户角色及权限控制 -2

    1.RabbitMQ的用户角色分类: none.management.policymaker.monitoring.administrator none 不能访问 management plugin ...

  9. RabbitMQ用户角色及权限控制(不错)

    ########################用户角色####################### RabbitMQ的用户角色分类:none.management.policymaker.moni ...

随机推荐

  1. mysql 中 datetime和 timestamp的区别

    DATETIME日期和时间的组合.支持的范围是'1000-01-01 00:00:00'到'9999-12-31 23:59:59'.MySQL以'YYYY-MM-DD HH:MM:SS'格式显示DA ...

  2. set_time_limit

    语法 : void set_time_limit (int seconds)说明 : 设定一个程式所允许执行的秒数,如果到达限制的时间,程式将会传回错误.它预设的限制时间是30秒,max_execut ...

  3. 3.Ubuntu下安装mysql并在windows下使用Navicat来连接

    一.安装mysql(只需要三条命令) 1.第一条命令(中间需要输入root用户密码): sudo apt-get install mysql-server 2.第二条命令: sudo apt-get ...

  4. 数据库中表的位置,在sysdatabases中

    name dbid sid mode status status2 crdate reserved category cmptlevel filename version master :: :: C ...

  5. cxgrid动态创建列

    cxgrid动态创建列 procedure TFrmRuleEdit.CreateCols;varColumn: TcxGridDBColumn;begincdsPowerPrj.First;whil ...

  6. Android-Kotlin-空值处理&字符串比较&常量

    空值处理: [案例一:] 1.Kotlin对控制处理很严格,默认就不能写null,否则编译都不通过: 描述Car汽车对象: package cn.kotlin.kotlin_base01 /** * ...

  7. hiho 第二周

    Trie树,第一次写,简单的建树+搜索 它的思路hiho上讲得很清楚,good~ #include<iostream> #include<string> using names ...

  8. mysql 幻象读

    [sql] view plain copy CREATE TABLE `t100` ( `id` bigint(20) NOT NULL default '0', `value` varchar(32 ...

  9. VBA 代码

    Private Declare PtrSafe Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA& ...

  10. JQuery实用技巧

    1.关于页面元素的引用通过jquery的$()引用元素包括通过id.class.元素名以及元素的层级关系及dom或者xpath条件等方法,且返回的对象为jquery对象(集合对象),不能直接调用dom ...