Spring security权限配置与使用大全

简介

Spring Security 是为了基于Spring的应用程序提供的声明式安全保护的安全性框架。Spring Security 提供了完整的安全性解决方案,它能够在Web请求级别和方法调用级别处理身份认证和授权。因为基于Spring框架,所以SPring Security充分使用了一览注入和面向切面技术。
Spring Security 本质上是借助一系列的 Servlet Filter来提供各种安全性功能,但这并不需要我们手动去添加或者创建多个Filter。实际上,我们仅需要配置一个Filter即可。
DelegatingFilterProxy 是一个特殊的Filter,他本身并没有做太多工作,而是将工作委托给了一个注入到Spring应用上下文的Filter实现类。

在本例中,主要讲解spring-security的配置与使用,实现方式为:

    1.将用户、权限、资源(url)采用数据库存储

    2.自定义过滤器,代替原有的 FilterSecurityInterceptor

    3.自定义实现 UserDetailsService、Filter、AccessDecisionManager和FilterInvocationSecurityMetadataSource并在配置文件进行相应的配置

    4.Spring-seculity在自定义用户验证的类加载必须早于Controller层创建

1.配置Spring-seculity.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:security="http://www.springframework.org/schema/security"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/security
    http://www.springframework.org/schema/security/spring-security.xsd">

    <security:http security="none" pattern="/login.jsp"/>
    <security:http security="none" pattern="/plugins/**"/>
    <security:http security="none" pattern="/css/**"/>
    <security:http security="none" pattern="/css/style.css"/>
    <security:http security="none" pattern="/img/**"/>
    <security:http security="none" pattern="/filer.jsp"/>
    <security:http security="none" pattern="/favicon.ico"/>
    <security:http  auto-config="true" use-expressions="false">
        <!--优先加载MyFilter自定义过滤器-->
        <security:custom-filter  before="FILTER_SECURITY_INTERCEPTOR" ref="myFilter"/>
        <!--固定用户拦截-->
    <!--<security:intercept-url pattern="/**" access="ROLE_USER" />-->

        <!--用户账户和密码表单验证-->
        <!--login-page="拦截跳转页面" login-processing-url="用户登陆验证路径"
            user-paramter=“页面账户名字” password-parameter=“页面密码”
            authentication-failure-url=“登陆失败跳转页面” default-target-rul=“登陆成功跳转页面”
         -->
        <security:form-login login-page="/login.jsp" login-processing-url="/login"
                             username-parameter="username" password-parameter="password"
                             authentication-failure-url="/filer.jsp" default-target-url="/jsp/all-admin-index.jsp"/>
        <!--用户退出登陆 -->
        <security:logout invalidate-session="true" logout-url="/logout" logout-success-url="/login.jsp"/>

        <!--禁止跨域请求-->
        <security:csrf disabled="true"/>

    </security:http>

    <bean id="myFilter" class="filter.MyFilter"/>
    <bean id="userinfo" class="ssm.service.UserinfoService"/>

    <!--固定用户账户和密码的验证-->
    <security:authentication-manager >
        <security:authentication-provider user-service-ref="userinfo">
            <!--固定用户名跟密码-->
<!--            <security:user-service>-->
<!--                <security:user name="user" password="{noop}user"-->
<!--                               authorities="ROLE_USER" />-->
<!--            </security:user-service>-->
        </security:authentication-provider>
    </security:authentication-manager>

</beans>

2.配置Web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <display-name>ssm-web</display-name>
    <welcome-file-list>
        <welcome-file>all-admin-login.jsp</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>
    <!--全局监听变量-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:ApplicantContext.xml,classpath:spring-security.xml</param-value>
    </context-param>
    <!--监听器-->
    <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!--默认过滤器-->
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!--spring-mvc中央处理器-->
    <servlet>
        <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!--字符编码转换器-->
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

3.自定义用户角色验证

package ssm.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
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 ssm.bean.Role;
import ssm.bean.UserInfo;
import ssm.dao.LoginDao;

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

@Service("userinfo")
public class UserinfoService implements IUserInfoService{

    @Autowired
    LoginDao loginDao;

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {    //将s传参从数据库查询是否用这个用户
        UserInfo info=loginDao.findByList(s);
        List<Role> list=info.getRoles();
         List<GrantedAuthority> role= new ArrayList<GrantedAuthority>();
        for(Role i:list){
            role.add(new SimpleGrantedAuthority("ROLE_"+i.getRolename()));
        }

        System.out.println(s);
        return new User(info.getUsername(), "{noop}"+info.getPassword(),info.getStatus()!=0?true:false,true,true,true, role);

    }

}

4.seculity自定义过滤器

package filter;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.security.access.SecurityMetadataSource;
import org.springframework.security.access.intercept.AbstractSecurityInterceptor;
import org.springframework.security.access.intercept.InterceptorStatusToken;
import org.springframework.security.web.FilterInvocation;

import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.servlet.*;
import java.io.IOException;

@Service("myFilter")
public class MyFilter extends AbstractSecurityInterceptor implements Filter {

    @Autowired
    private FilterInvocationSecurityMetadataSource securityMetadataSource;

    @Override
    public Class<?> getSecureObjectClass() {
        return FilterInvocation.class;
    }

    @Override
    public SecurityMetadataSource obtainSecurityMetadataSource() {
        return securityMetadataSource;
    }

    @Autowired
    public void setMyAccessDecisionManager(MyAccessDescisionManager myAccessDescisionManager) {
        super.setAccessDecisionManager(myAccessDescisionManager);
    }
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        System.out.println("------------MyFilterSecurityInterceptor.doFilter()-----------开始拦截器了....");
        FilterInvocation fi = new FilterInvocation(request, response, chain);

        InterceptorStatusToken token = super.beforeInvocation(fi);

        try {
            fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            super.afterInvocation(token, null);
        }

        System.out.println("------------MyFilterSecurityInterceptor.doFilter()-----------拦截器该方法结束了....");
    }

    @Override
    public void destroy() {

    }
}

5.自定义用户权限验证

package filter;

import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.Iterator;

@Service
public class MyAccessDescisionManager implements AccessDecisionManager {

    @Override
    public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes)throws AccessDeniedException, InsufficientAuthenticationException {
        // TODO Auto-generated method stub
         System.out.println("MyAccessDescisionManager.decide()------------------验证用户是否具有一定的权限--------");
            if(configAttributes==null) return;
            Iterator<ConfigAttribute> it = configAttributes.iterator();
            while(it.hasNext()){
                String needResource = it.next().getAttribute();
                //authentication.getAuthorities()  用户所有的权限
                for(GrantedAuthority ga:authentication.getAuthorities()){
                    System.out.println("ROLE_"+needResource);
                    System.out.println(ga.getAuthority());
                    if(("ROLE_"+needResource).equals(ga.getAuthority())){
                        return;
                    }
                }
            }
            throw new AccessDeniedException("--------MyAccessDescisionManager:decide-------权限认证失败!");  

    }

    @Override
    public boolean supports(ConfigAttribute attribute) {
        // TODO Auto-generated method stub
        return true;
    }

    @Override
    public boolean supports(Class<?> clazz) {
        // TODO Auto-generated method stub
        return true;
    }

}

6.自定义初始化用户角色和权限属性

package filter;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.util.AntPathMatcher;
import ssm.bean.Premission;
import ssm.bean.Role;
import ssm.dao.LoginDao;
import ssm.dao.MapperRoleDao;
import ssm.dao.MapperUserDao;

import java.util.*;

@Service
public class MySecurityMetadataSource implements FilterInvocationSecurityMetadataSource {

    /*@Autowired
    private IUserDao userDao; */

    @Autowired
    private LoginDao loginDao;

    /* 保存资源和权限的对应关系  key-资源url  value-权限 */
    private static Map<String, Collection<ConfigAttribute>> resourceMap = null;
    private AntPathMatcher urlMatcher = new AntPathMatcher();

    public MySecurityMetadataSource() {
        //loadResourcesDefine();
    }  

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }  

    private void loadResourcesDefine(){
        resourceMap = new HashMap<String,Collection<ConfigAttribute>>();

        System.out.println("MySecurityMetadataSource.loadResourcesDefine()--------------开始加载资源列表数据--------");
        List<Role> roles;
        try {
            roles = loginDao.findByROleList();
             for(Role role : roles){
                    List<Premission> permissions = role.getPremission();
                    for(Premission permission : permissions){
                        Collection<ConfigAttribute> configAttributes = null;
                        ConfigAttribute configAttribute = new SecurityConfig(role.getRolename());
                        if(resourceMap.containsKey(permission.getUrl())){
                            configAttributes = resourceMap.get(permission.getUrl());
                            configAttributes.add(configAttribute);
                        }else{
                            configAttributes = new ArrayList<ConfigAttribute>() ;
                            configAttributes.add(configAttribute);
                            resourceMap.put(permission.getUrl(), configAttributes);
                        }
                    }
                }
                System.out.println("11");
                Set<String> set = resourceMap.keySet();
                Iterator<String> it = set.iterator();
                int  i=0;
                while(it.hasNext()){
                    String s = it.next();
                    System.out.println(++i+"key:"+s+"|value:"+resourceMap.get(s));
                }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
    /*
     * 根据请求的资源地址,获取它所拥有的权限
     */
    @Override
    public Collection<ConfigAttribute> getAttributes(Object obj)
            throws IllegalArgumentException {
        if(null==resourceMap||resourceMap.size() == 0) {
            loadResourcesDefine();
        }
        //获取请求的url地址
        String url = ((FilterInvocation)obj).getRequestUrl();
        System.out.println("MySecurityMetadataSource:getAttributes()---------------请求地址为:"+url);
        Iterator<String> it = resourceMap.keySet().iterator();
        while(it.hasNext()){
            String _url = it.next();
            if(url.indexOf("?")!=-1){
                url = url.substring(0, url.indexOf("?"));
            }
            if(urlMatcher.match(_url,url)){
                System.out.println("MySecurityMetadataSource:getAttributes()---------------需要的权限是:"+resourceMap.get(_url));
                return resourceMap.get(_url);
            }

        }
        Collection<ConfigAttribute> nouse = new ArrayList<ConfigAttribute>();
        nouse.add(new SecurityConfig("无相应权限"));
        return nouse;
    }  

    @Override
    public boolean supports(Class<?> arg0) {
        System.out.println("MySecurityMetadataSource.supports()---------------------");
        return true;
    }  

}

到此这篇关于Spring-seculity权限使用的文章就介绍到这了,更多相关Spring-seculity权限使用内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • springboot集成springsecurity 使用OAUTH2做权限管理的教程

    Spring Security OAuth2 主要配置,注意application.yml最后的配置resource filter顺序配置,不然会能获取token但是访问一直 没有权限 WebSecurityConfigurerAdapter 所在服务器的web配置 AuthorizationServerConfigurerAdapter 认证服务器配置 ResourceServerConfigurerAdapter 资源服务器配置 这两个配置在 OAuth2Config.java 权限有几种模

  • SpringSecurity怎样使用注解控制权限

    一般的系统在权限设计上,都会分为角色.权限(RDBC),复杂一点的可能会有用户组.组织之类的概念. 用户的权限是写死的,对应于后台的接口或者资源,是没办法改变的,一般不对用户开放修改权限. 管理员用户可以通过给角色分配权限的方式,来实现访问控制. 所以当我们写过滤器,或者用一些安全框架时(比如Shiro,Spring Security),也需要将可变的"角色",转化为不可变的"权限",注入到框架中. 具体的可以看我之前写的一篇(Spring Security整合jw

  • SpringBoot+Vue前后端分离,使用SpringSecurity完美处理权限问题的解决方法

    当前后端分离时,权限问题的处理也和我们传统的处理方式有一点差异.笔者前几天刚好在负责一个项目的权限管理模块,现在权限管理模块已经做完了,我想通过5-6篇文章,来介绍一下项目中遇到的问题以及我的解决方案,希望这个系列能够给小伙伴一些帮助.本系列文章并不是手把手的教程,主要介绍了核心思路并讲解了核心代码,完整的代码小伙伴们可以在GitHub上star并clone下来研究.另外,原本计划把项目跑起来放到网上供小伙伴们查看,但是之前买服务器为了省钱,内存只有512M,两个应用跑不起来(已经有一个V部落开

  • Spring Boot中使用 Spring Security 构建权限系统的示例代码

    Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架.它提供了一组可以在Spring应用上下文中配置的Bean,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作. 权限控制是非常常见的功能,在各种后台管理里权限控制更是重中之重.在Spring Boot中使用 Spring Security 构建权限系统是非常轻松和简单的.下面我们就来快速入门 Spring Security .在开始前我们需要一对

  • Spring Security如何使用URL地址进行权限控制

    这篇文章主要介绍了Spring Security如何使用URL地址进行权限控制,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 目的是:系统内存在很多不同的用户,每个用户具有不同的资源访问权限,具体表现就是某个用户对于某个URL是无权限访问的.需要Spring Security忙我们过滤. FilterSecurityInterceptor是Spring Security进行URL权限判断的,FilterSecurityInterceptor又继

  • Spring security用户URL权限FilterSecurityInterceptor使用解析

    这篇文章主要介绍了Spring security用户URL权限FilterSecurityInterceptor使用解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 用户通过浏览器发送URL地址,由FilterSecurityInterceptor判断是否具有相应的访问权限. 对于用户请求的方法权限,例如注解@PreAuthorize("hasRole('ADMIN')"),由MethodSecurityInterceptor判断

  • Spring security权限配置与使用大全

    简介 Spring Security 是为了基于Spring的应用程序提供的声明式安全保护的安全性框架.Spring Security 提供了完整的安全性解决方案,它能够在Web请求级别和方法调用级别处理身份认证和授权.因为基于Spring框架,所以SPring Security充分使用了一览注入和面向切面技术. Spring Security 本质上是借助一系列的 Servlet Filter来提供各种安全性功能,但这并不需要我们手动去添加或者创建多个Filter.实际上,我们仅需要配置一个F

  • java中自定义Spring Security权限控制管理示例(实战篇)

    背景描述 项目中需要做细粒的权限控制,细微至url + httpmethod (满足restful,例如: https://.../xxx/users/1, 某些角色只能查看(HTTP GET), 而无权进行增改删(POST, PUT, DELETE)). 表设计 为避嫌,只列出要用到的关键字段,其余敬请自行脑补. 1.admin_user 管理员用户表, 关键字段( id, role_id ). 2.t_role 角色表, 关键字段( id, privilege_id ). 3.t_privi

  • Spring Security权限管理实现接口动态权限控制

    SpringBoot实战电商项目mall(30k+star)地址:https://github.com/macrozheng/mall 摘要 权限控管理作为后台管理系统中必要的功能,mall项目中结合Spring Security实现了基于路径的动态权限控制,可以对后台接口访问进行细粒度的控制,今天我们来讲下它的后端实现原理. 前置知识 学习本文需要一些Spring Security的知识,对Spring Security不太了解的朋友可以看下以下文章. mall整合SpringSecurity

  • Spring Security权限管理小结

    目录 1 Spring Security配置用户名和密码 方式一:在application.properties文件中配置 方式二:代码配置 一.查询user用户所具有的角色 二.配置SecurityConfig 2 HttpSecurity的配置 3 登录/注销表单详细配置 4 多个HttpSecurity的配置 5 密码加密 6 方法安全 7 基于数据库的认证 8 角色继承(在securityConfig中加入代码段) 9 动态配置权限 1 Spring Security配置用户名和密码 方

  • spring security动态配置url权限的2种实现方法

    缘起 标准的RABC, 权限需要支持动态配置,spring security默认是在代码里约定好权限,真实的业务场景通常需要可以支持动态配置角色访问权限,即在运行时去配置url对应的访问角色. 基于spring security,如何实现这个需求呢? 最简单的方法就是自定义一个Filter去完成权限判断,但这脱离了spring security框架,如何基于spring security优雅的实现呢? spring security 授权回顾 spring security 通过FilterCh

  • 详解Spring Security如何配置JSON登录

    spring security用了也有一段时间了,弄过异步和多数据源登录,也看过一点源码,最近弄rest,然后顺便搭oauth2,前端用json来登录,没想到spring security默认居然不能获取request中的json数据,谷歌一波后只在stackoverflow找到一个回答比较靠谱,还是得要重写filter,于是在这里填一波坑. 准备工作 基本的spring security配置就不说了,网上一堆例子,只要弄到普通的表单登录和自定义UserDetailsService就可以.因为需

  • 话说Spring Security权限管理(源码详解)

    最近项目需要用到Spring Security的权限控制,故花了点时间简单的去看了一下其权限控制相关的源码(版本为4.2). AccessDecisionManager spring security是通过AccessDecisionManager进行授权管理的,先来张官方图镇楼. AccessDecisionManager AccessDecisionManager 接口定义了如下方法: //调用AccessDecisionVoter进行投票(关键方法) void decide(Authent

  • Spring Security权限想要细化到按钮实现示例

    目录 引言 1. 权限颗粒度 2. 权限表 3. 后端权限判断 4. 角色与权限 4.1 RBAC 简介 4.2 RBAC 的提出 4.3 RBAC 三原则 4.4 RBAC 模型分类 4.4.1 RBAC0 4.4.2 RBAC1 4.4.4 RBAC3 4.5 扩展 5. 表设计 6. 代码实现 引言 因为写了不少 Spring Security 文章的缘故,所以总是有小伙伴来问松哥:按钮级别的权限怎么实现?甚至有一些看过 vhr 的小伙伴也问这种问题,其实有的时候搞得我确实挺郁闷的,最近刚

  • 详解Spring Security 简单配置

    开发环境 maven idea jdk 1.8 tomcat 8 配置spring mvc + spring security pom.xml <properties> <spring.version>4.3.8.RELEASE</spring.version> <spring-sercurity.version>4.2.2.RELEASE</spring-sercurity.version> </properties> <de

  • Spring Security基本配置方法解析

    Spring Security 是一个功能强大且可高度自定义的身份验证和访问控制框架. 它是保护基于Spring的应用程序的事实上的标准. Spring Security 是一个专注于为Java应用程序提供身份验证和授权的框架. 与所有Spring项目一样,Spring Security的真正强大之处在于它可以轻松扩展以满足自定义要求 先建立一个maven多模块工程,如下: spring-security:父模块 spring-security-browser:处理浏览器相关的授权认证,最终作为

随机推荐