1. 程式人生 > >springboot+security restful許可權控制官方推薦(五)

springboot+security restful許可權控制官方推薦(五)

繼前幾篇部落格將使用者、角色、許可權資訊都存在資料,實現管理許可權到請求方法級別。感覺那種實現方式比較雞肋,不太實用。所以今天說一下,官方推薦的註解方式控制權限到請求方法級別的實現。

官方推薦的方法是將使用者、角色資訊存在資料庫,而角色和許可權的對應關係,通過註解的方式寫死在controller上。

廢話不多說,上程式碼;

1. 資料庫設計

這裡寫圖片描述

insert into SYS_USER (id,username, password) values (1,'admin', '$2a$10$YwbP2rm18bOWOrkJHybp5uTRHCpn5Rk8rGT6fogf0KdtNY7jzmebu'
);
insert into SYS_USER (id,username, password) values (2,'abel', '$2a$10$/h0hVDo3A78lEHhsIckGz.nfXGgUFx2yB4bfy6o15RZi8VlZqt.PK'); insert into SYS_ROLE(id,name) values(1,'ROLE_ADMIN'); insert into SYS_ROLE(id,name) values(2,'ROLE_USER');

2. 修改WebSecurityConfig 檔案

此處使用了 BCryptPasswordEncoder 密碼加密

package com
.us.example.config; import com.us.example.security.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; /** * Created by yangyibo on 17/1/18. */ @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(securedEnabled = true)// 控制權限註解 public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private CustomUserService customUserService; @Autowired protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(customUserService).passwordEncoder(new BCryptPasswordEncoder()); } @Override protected void configure(HttpSecurity http) throws Exception { http .csrf().disable() .authorizeRequests() .antMatchers("/users/**") .authenticated() .antMatchers(HttpMethod.POST) .authenticated() .antMatchers(HttpMethod.PUT) .authenticated() .antMatchers(HttpMethod.DELETE) .authenticated() .antMatchers("/**") .permitAll() .and() .sessionManagement() .and() .httpBasic(); } }

3. 修改SysUser 類實現 UserDetails介面

package com.us.example.domain;

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

import java.util.Collection;
import java.util.List;

/**
 * Created by yangyibo on 17/1/17.
 */

public class SysUser implements UserDetails {  // implements UserDetails 用於登入時 @AuthenticationPrincipal 標籤取值
    private Integer id;
    private String username;
    @JsonIgnore
    private String password;
    private String rawPassword;
    @JsonIgnore
    private List<SysRole> roles;
    private List<? extends GrantedAuthority> authorities;


    public Integer getId() {
        return id;
    }

    public void setId(Integer 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 List<SysRole> getRoles() {
        return roles;
    }

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

    public String getRawPassword() {
        return rawPassword;
    }

    public void setRawPassword(String rawPassword) {
        this.rawPassword = rawPassword;
    }


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

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

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


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

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

    public void setGrantedAuthorities(List<? extends GrantedAuthority> authorities) {
        this.authorities = authorities;
    }
}

4. 修改 CustomUserService 類

package com.us.example.security;

import com.us.example.dao.UserDao;
import com.us.example.domain.SysRole;
import com.us.example.domain.SysUser;
import org.slf4j.LoggerFactory;
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;

/**
 * Created by yangyibo on 17/1/18.
 */
@Service
public class CustomUserService implements UserDetailsService { //自定義UserDetailsService 介面

    @Autowired
    UserDao userDao;
    private static final org.slf4j.Logger logger = LoggerFactory.getLogger(CustomUserService.class);

    @Override
    public UserDetails loadUserByUsername(String username) { //重寫loadUserByUsername 方法獲得 userdetails 型別使用者

        SysUser user = userDao.findByUserName(username);
        if(user == null){
            throw new UsernameNotFoundException("使用者名稱不存在");
        }
        List<SimpleGrantedAuthority> authorities = new ArrayList<>();
        //用於新增使用者的許可權。只要把使用者許可權新增到authorities 就萬事大吉。
        for(SysRole role:user.getRoles())
        {
            authorities.add(new SimpleGrantedAuthority(role.getName()));
            logger.info("loadUserByUsername: " + user);
        }
        user.setGrantedAuthorities(authorities); //用於登入時 @AuthenticationPrincipal 標籤取值
        return user;
    }
}

5. 新增登入controller

新建LoginController

package com.us.example.controller;

import com.us.example.domain.SysUser;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;


/**
 * Created by yangyibo on 17/3/1.
 */
@RestController
public class LoginController {

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

6. 修改 HomeController 新增許可權控制

package com.us.example.controller;

import com.us.example.domain.SysUser;
import com.us.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Controller;
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.ResponseBody;

/**
 * Created by yangyibo on 17/1/18.
 */
@Controller
@RequestMapping("/users")
public class HomeController {
    @Autowired
    UserService userService;

    @RequestMapping(method = RequestMethod.GET)
    @ResponseBody
    public String getUsers() {
        return "getUsers";
    }

    @Secured({"ROLE_ADMIN","ROLE_USER"})//此方法只允許 ROLE_ADMIN 和ROLE_USER 角色 訪問
    @RequestMapping(method = RequestMethod.POST)
    @ResponseBody
    public Object save(@RequestBody SysUser user) {
        return  userService.create(user);
    }


    @Secured("ROLE_ADMIN")//此方法只允許 ROLE_ADMIN 角色訪問
    @RequestMapping(method = RequestMethod.PUT)
    @ResponseBody
    public String update() {
        return "updateUser";
    }

    @Secured("ROLE_ADMIN")//此方法只允許 ROLE_ADMIN 角色訪問
    @RequestMapping(method = RequestMethod.DELETE)
    @ResponseBody
    public String delete() {
        return "deleteUser";
    }

}

7. 測試

使用admin 登入

可以訪問 /users 路徑下的get、post、put、delete 四個請求方法

使用abel 登入
可以訪問 /users 路徑下的get、post 兩個請求方法
訪問 put、delete 方法會拋403 沒有許可權異常

相關推薦

springboot+security restful許可權控制官方推薦

繼前幾篇部落格將使用者、角色、許可權資訊都存在資料,實現管理許可權到請求方法級別。感覺那種實現方式比較雞肋,不太實用。所以今天說一下,官方推薦的註解方式控制權限到請求方法級別的實現。 官方推薦的方法是將使用者、角色資訊存在資料庫,而角色和許可權的對應關係,通過

springboot+redis實現熱詞搜尋推薦Java

import cc.datebook.common.JsonResult; import cc.datebook.entity.BookInfo; import cc.datebook.enums.ResultCode; import cc.datebo

restful架構風格設計準則用戶認證和session管理

好的 困難 是否 ica 過程 集成 設計 管理服務器 系統 讀書筆記,原文鏈接:http://www.cnblogs.com/loveis715/p/4669091.html,感謝作者! Authentication   其實在上一節中,我們已經提出了無狀態約束給REST

winform控制元件縮寫對話方塊

winform控制元件縮寫(五)對話方塊 序號 縮寫 空間名 1 cld ColorDialog 2 fbd Fold

JavaFX UI控制元件教程之Radio Button

本章討論單選按鈕控制元件和RadioButton類,該類的一個專門實現ToggleButton。 可以選擇或取消選擇單選按鈕控制元件。通常,單選按鈕組合成一個組,其中一次只能選擇一個按鈕。此行為將它們與切換按鈕區分開來,因為組中的所有切換按鈕都可以處於取消選擇狀態。

乾貨|個性化推薦系統五大研究熱點之可解釋推薦

【編者按】微軟亞洲研究院社會計算組的研究員們從深度學習、知識圖譜、強化學習、使用者畫像、可解釋性推薦等五個方面,展望了未來推薦系統發展的方向。 在前幾篇文章中,我們分別介紹了深度學習、知識圖譜、強化學習、使用者畫像在推薦系統中的應用以及未來可能的研究方向。在今天的最後一篇文章中,我們將介紹推薦系

selenium webdriver 學習總結-Selenium 控制測試流

一、同步測試流 1、隱式等待(不常用) 此等待方式是在查詢元素時,元素沒有立即出現,將等待指定時間後再去查詢DOM,預設為0,一旦設定後,將存在webDriver物件的生命週期中 示例:driver.manage().timeouts().implicitlyWait(10

springboot原始碼解析-管中窺豹系列之排序

# 一、前言 - Springboot原始碼解析是一件大工程,逐行逐句的去研究程式碼,會很枯燥,也不容易堅持下去。 - 我們不追求大而全,而是試著每次去研究一個小知識點,最終聚沙成塔,這就是我們的springboot原始碼管中窺豹系列。 ![ 簡介 ](https://zhangbin1989.gitee.

SpringBoot中使用Spring Security實現許可權控制

Spring Security,這是一個專門針對基於Spring的專案的安全框架,它主要是利用了AOP來實現的。以前在Spring框架中使用Spring Security需要我們進行大量的XML配置,但是,Spring Boot針對Spring Security

vue許可權控制攻略iview-admin

vue許可權控制攻略(iview-admin) 作者:輕酌~淺醉 1,方式 在meta中新增access 只顯示在當前使用者組中定義的 第一個引數為當前要訪問的頁面的name傳進去 ,第二個引數為使用者的許可權欄位列表(登入之後通過介面獲取) canTurn

Shiro——實現許可權控制demo思路包含自定義標籤hasAnyPermission

在很多系統中需要使用許可權控制,來控制不同角色的人訪問不同的資源。表達能力不好,不喜勿噴! 環境:eclipse4.5.2+oracle11g+hibernate4+spring4+shiro+jboss 原始碼(工程)+ 資料表sql(包含初始化資料)+hibernat

在Spring Boot中使用Spring Security實現許可權控制

Spring Boot框架我們前面已經介紹了很多了,相信看了前面的部落格的小夥伴對Spring Boot應該有一個大致的瞭解了吧,如果有小夥伴對Spring Boot尚不熟悉,可以先移步這裡從SpringMVC到Spring Boot,老司機請略過。OK,那我們

Spring Security原始碼分析十:Spring Security 頁面許可權控制

Spring Security是一個能夠為基於Spring的企業應用系統提供宣告式的安全訪問控制解決方案的安全框架。它提供了一組可以在Spring應用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反轉Inversion of Contr

JAVA程式設計思想學習筆記訪問許可權控制

訪問許可權控制 包:庫單元 打包關鍵字:package 匯入關鍵字:import package必須是除註釋以外的第一句程式程式碼。 java直譯器的執行過程: 找出環境變數CLASSPATH。 CLASSPATH包含一個或多個目錄,用作查詢.class檔案

基於RESTful風格的controller層SpringMVC的測試:MockMVCSpringBoot和JUnit4測試環境

個人程式碼 首先附上個人測試過的程式碼: /** * Description * * @author Amethyst * @date 2017/5/2 15:28 //SpringRunner繼承自:SpringJUnit4ClassR

ZooKeeper系列—— ACL 許可權控制

一、前言 為了避免儲存在 Zookeeper 上的資料被其他程式或者人為誤修改,Zookeeper 提供了 ACL(Access Control Lists) 進行許可權控制。只有擁有對應許可權的使用者才可以對節點進行增刪改查等操作。下文分別介紹使用原生的 Shell 命令和 Apache Curator 客

C#基礎知識-流程控制的應用

相關 ats 循環 nbsp 使用 logs 嘗試 exc 設置斷點 流程控制我們在編程中運用到的地方非常的多,在上篇中僅僅只是簡單的介紹每一種的使用,並沒有運用到實例中,很難去理解它真正的作用。下面我們將實際的運用流程控制的代碼寫一些實例相關的程序,加深對流程控制的理解,

log4j——如何控制不同目的地的日誌輸出?

arc config scribe 原則 log4j min logging 主機 我們 一:測試環境與log4j(一)——為什麽要使用log4j?一樣,這裏不再重述 1 老規矩,先來個栗子,然後再聊聊感受 package test.l

樹莓派進階之路 (023) - Windows下用串行連接控制樹莓派

最新版 一個 問題 conn get 鏡像 under tty 打開 轉載:http://shumeipai.nxez.com/2014/05/04/under-windows-serial-connection-control-raspberry-pi.html 在沒有鍵

RobotFrameWork控制流之if語句——Run Keyword If

net 2.4 content img 執行 控制流 條件 text csdn 引自:http://blog.csdn.net/mengfanbo123/article/details/8891378 5.1 語句簡介 robotframework中的if語句是使