您的位置:首页 > 编程语言 > Java开发

springboot-30-security(三)使用注解实现权限控制

2017-08-17 17:28 1036 查看
上个博客: http://www.cnblogs.com/wenbronk/p/7381252.html中, 实现了经典5表对用户进行权限的控制, 但太过于繁琐了, 官方推荐的方式是将用户和角色存储数据库, 权限直接在要访问的接口上进行控制

(我感觉更麻烦...每个接口都需要指定)

本篇基于第一个, security: http://www.cnblogs.com/wenbronk/p/7379865.html

一, 数据库: (更多可见 security(1) )

1, 数据表:

insert into SYS_USER (id,username, password) values (1,'vini', '$2a$10$n7sdY5rR1X3XOfZR6o2R.OdW0vvz3uidz0UEzVKV0CEyu0hGwIch.');
insert into SYS_USER (id,username, password) values (2,'bronk', '$2a$10$n7sdY5rR1X3XOfZR6o2R.OdW0vvz3uidz0UEzVKV0CEyu0hGwIch.');

insert into SYS_ROLE(id,name) values(1,'ROLE_ADMIN');
insert into SYS_ROLE(id,name) values(2,'ROLE_USER');

insert into SYS_ROLE_USER(SYS_USER_ID,sys_role_id) values(1,1);
insert into SYS_ROLE_USER(SYS_USER_ID,sys_role_id) values(2,2);


View Code
这儿使用了 Bcrpy强hash加密, 我设置的密码为 123,

更多可见: http://blog.csdn.net/u012373815/article/details/60465776

3, 映射实体

SysUser.groovy

package com.wenbronk.security.entity

import com.fasterxml.jackson.annotation.JsonIgnore
import org.springframework.security.core.GrantedAuthority
import org.springframework.security.core.userdetails.UserDetails

/**
* Created by wenbronk on 2017/8/14.
*/
class SysUser implements UserDetails {
int id
String username
@JsonIgnore
String password
String rawPass
@JsonIgnore
List<SysRole> roles
List<? extends GrantedAuthority> authorities

@Override
@JsonIgnore
Collection<? extends GrantedAuthority> getAuthorities() {
return authorities
}

@Override
@JsonIgnore
boolean isAccountNonExpired() {
return true
}

@Override
@JsonIgnore
boolean isAccountNonLocked() {
return true
}

@Override
@JsonIgnore
boolean isCredentialsNonExpired() {
return true
}

@Override
@JsonIgnore
boolean isEnabled() {
return true
}

@Override
public String toString() {
return "SysUser{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", rawPass='" + rawPass + '\'' +
", roles=" + roles +
", authorities=" + authorities +
'}';
}
}


SysRole.groovy

package com.wenbronk.security.entity
/**
* Created by wenbronk on 2017/8/14.
*/
class SysRole {
int id
String name

@Override
public String toString() {
return "SysRole{" +
"id=" + id +
", name=" + name +
'}';
}
}


4, mapper

SysUserMapper.groovy

package com.wenbronk.security.mapper

import com.wenbronk.security.entity.SysUser

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


SysUserMapper.xml

<?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>


二, security

1, WebSecurityConfig.groovy

package com.wenbronk.security.security.config

import com.wenbronk.security.security.interceptor.MyFilterSecurityInterceptor
import com.wenbronk.security.security.service.CustomUserService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Configuration
import org.springframework.http.HttpMethod
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

import javax.inject.Inject
/**
* Created by wenbronk on 2017/8/15.
*/
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true) // 控制权限注解
class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Inject
CustomUserService customUserService;
@Autowired
MyFilterSecurityInterceptor myFilterSecurityInterceptor

/**
* 设置加密方式为 BCrypt强hash
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserService).passwordEncoder(new BCryptPasswordEncoder());
}

@Override
protected void configure(HttpSecurity http) throws Exception {
// 关闭 csrf()
http.csrf().disable()
.authorizeRequests()
.antMatchers("/users**").authenticated()
.antMatchers(HttpMethod.POST).authenticated()
.antMatchers(HttpMethod.PUT).authenticated()
.antMatchers(HttpMethod.DELETE).authenticated()
.antMatchers("/**")
.permitAll()
.and()
.sessionManagement()
// 使用basic认证登陆
.and().httpBasic()
}
}


这儿需要关闭 csrf 和使用 basic 认证, 相信可见:

http://blog.csdn.net/u012373815/article/details/55047285 http://blog.csdn.net/u012373815/article/details/56832167[/code] 
CustomerUserService.groovy

package com.wenbronk.security.security.service

import com.wenbronk.security.entity.SysUser
import com.wenbronk.security.mapper.SysUserMapper
import org.springframework.security.core.GrantedAuthority
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 javax.inject.Inject
/**
* Created by wenbronk on 2017/8/15.
*/
@Service
class CustomUserService implements UserDetailsService {

@Inject
SysUserMapper sysUserMapper
//    @Inject
//    SysPermissionMapper sysPermissionMapper

@Override
UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
def sysUser = sysUserMapper.findByUserName(s) as SysUser
assert sysUser != null

List<GrantedAuthority> authorities = new ArrayList<>()
sysUser.getRoles().each { role ->
// 将用户的权限添加到 authrities中就可以了
authorities.add(new SimpleGrantedAuthority(role.getName()))
}
sysUser.setAuthorities(authorities)
return sysUser

}
}


三, 接口控制:

登陆使用的

@RequestMapping(value = "/login")
public Object login(@AuthenticationPrincipal SysUser loginUser, @RequestParam(name = "logout", required = false) String logout) {
if (logout != null) {
return null
}
if (loginUser != null) {
return loginUser
}
return null
}


权限接口控制:

package com.wenbronk.security.controller

import com.wenbronk.security.entity.SysUser
import org.springframework.security.access.annotation.Secured
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestMethod
import org.springframework.web.bind.annotation.RestController
/**
* Created by wenbronk on 2017/8/17.
*/
@RestController
@RequestMapping("/users")
class HomeController {

/**
* 所有可访问
*/
@RequestMapping(method = RequestMethod.GET)
String getusers() {
'getUsers'
}

@Secured(value = ['ROLE_ADMIN', 'ROLE_USER'])
@RequestMapping(method = RequestMethod.POST)
String save(@RequestBody SysUser user) {
user.toString()
}

/**
* 只有admin可访问
*/
@Secured(value = ['ROLE_ADMIN'])
@RequestMapping(method = RequestMethod.PUT)
String update() {
'updateUser'
}

@Secured(value = ['ROLE_ADMIN'])
@RequestMapping(method = RequestMethod.DELETE)
String delete() {
'deleteUser'
}

}


四, 访问:

1, get访问



2, post访问, 请求体为:

{
"id": 1,
"username": "vini",
"password": "123",
"rawPass": "123"
}




3, put请求, 此处使用的用户没有权限



4, delete请求, 换有权限的用户



这样, 就可以实现具体方法的访问权限控制, 包括rest请求

ps: basic64登陆, 需要密码, 可以使用工具生成, 也可以抓包

原博客地址:

http://blog.csdn.net/u012373815/article/details/59749385
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: