zoukankan      html  css  js  c++  java
  • SpringSecurity登录用户权限验证demo

    准备:

      1、Spring Security需要自定义一个继承至AbstractSecurityInterceptor的Filter,该抽象类包含了AccessDecisionManager(决策管理器)、AuthenticationManager(身份认证管理器)的setter, 可以通过Spring自动注入,另外,资源角色授权器需要单独自定义注入

      2、AccessDecisionManager(决策管理器)的实现需要实现AccessDecisionManager接口,在实现的decide(Authentication arg0, Object arg1,Collection<ConfigAttribute> arg2)方法中,需要将用户具有的角色权限Collection<GrantedAuthority> grantedAuthorities=arg0.getAuthorities();与访问该资源所需要的金额角色权限Collection<ConfigAttribute> arg2进行比较,若有一个角色匹配,则放行允许该用户访问此资源。

      3、AuthenticationManager(身份认证管理器)可以通过applicationContext-security.xml中<authentication-manager />标签实现。该标签需要引用一个实现了UserDetailService接口的类。该类的loadUserByUsername(String username)方法,通过传进来的用户名返回一个User对象,构造该User对象时需要传入GrantedAuthority的Collection,此时可以通过不同的用户名赋予不同的GrantedAuthority。

      4、资源角色授权器需要实现FilterInvocationSecurityMetadataSource接口。请求的资源所需要的角色权限在服务器启动时候就已经确定的,所以在该实现类的构造方法中需要确定每一种资源需要那些角色权限,通过一个Map<String, List<ConfigAttribute>>即可将所有资源所需要的List<ConfigAttribute>存储起来。该实现类中getAttributes(Object arg0)方法,可以通过请求的url返回对应的Collection<ConfigAttribute>,通过传进来的FilterInvocation可以得到RequestUrl,然后遍历Map<String, List<ConfigAttribute>>。

    一、定义继承至AbstractSecurityInterceptor的CustomSecurityFilter。

    View Code
     1 package com.spring.security.demo;
     2 
     3 import java.io.IOException;
     4 
     5 import javax.servlet.Filter;
     6 import javax.servlet.FilterChain;
     7 import javax.servlet.FilterConfig;
     8 import javax.servlet.ServletException;
     9 import javax.servlet.ServletRequest;
    10 import javax.servlet.ServletResponse;
    11 
    12 import org.springframework.security.access.SecurityMetadataSource;
    13 import org.springframework.security.access.intercept.AbstractSecurityInterceptor;
    14 import org.springframework.security.access.intercept.InterceptorStatusToken;
    15 import org.springframework.security.web.FilterInvocation;
    16 import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
    17 
    18 public class CustomSecurityFilter extends AbstractSecurityInterceptor implements
    19         Filter
    20 {
    21     private FilterInvocationSecurityMetadataSource securityMetadataSource;
    22 
    23     public FilterInvocationSecurityMetadataSource getSecurityMetadataSource()
    24     {
    25         return securityMetadataSource;
    26     }
    27 
    28     public void setSecurityMetadataSource(
    29             FilterInvocationSecurityMetadataSource securityMetadataSource)
    30     {
    31         this.securityMetadataSource = securityMetadataSource;
    32     }
    33 
    34     @Override
    35     public void destroy()
    36     {
    37         // TODO Auto-generated method stub
    38 
    39     }
    40 
    41     @Override
    42     public void doFilter(ServletRequest arg0, ServletResponse arg1,
    43             FilterChain arg2) throws IOException, ServletException
    44     {
    45         FilterInvocation fileInvocation = new FilterInvocation(arg0, arg1, arg2);
    46         InterceptorStatusToken interceptorStatusToken = this
    47                 .beforeInvocation(fileInvocation);
    48         fileInvocation.getChain().doFilter(arg0, arg1);
    49         this.afterInvocation(interceptorStatusToken, null);
    50     }
    51 
    52     @Override
    53     public void init(FilterConfig arg0) throws ServletException
    54     {
    55         // TODO Auto-generated method stub
    56 
    57     }
    58 
    59     @Override
    60     public Class<? extends Object> getSecureObjectClass()
    61     {
    62         return FilterInvocation.class;
    63     }
    64 
    65     @Override
    66     public SecurityMetadataSource obtainSecurityMetadataSource()
    67     {
    68         return this.securityMetadataSource;
    69     }
    70 
    71 }

    二、定义AccessDecisionManager(决策管理器)、AuthenticationManager(身份认证管理器)、实现了UserDetailService接口的CustomUserDetailService。

    CustomAccessDecisionManager.java

    View Code
     1 package com.spring.security.demo.dependent.components;
     2 
     3 import java.util.Collection;
     4 import java.util.Iterator;
     5 
     6 import org.springframework.security.access.AccessDecisionManager;
     7 import org.springframework.security.access.AccessDeniedException;
     8 import org.springframework.security.access.ConfigAttribute;
     9 import org.springframework.security.access.SecurityConfig;
    10 import org.springframework.security.authentication.InsufficientAuthenticationException;
    11 import org.springframework.security.core.Authentication;
    12 import org.springframework.security.core.GrantedAuthority;
    13 
    14 public class CustomAccessDecisionManager implements AccessDecisionManager
    15 {
    16     /**
    17      * Authentication arg0 --->用户具有的角色权限 
    18      * Collection<ConfigAttribute> arg2 --->访问该资源所需的角色权限
    19      */
    20     @Override
    21     public void decide(Authentication arg0, Object arg1,
    22             Collection<ConfigAttribute> arg2) throws AccessDeniedException,
    23             InsufficientAuthenticationException
    24     {
    25         Iterator<ConfigAttribute> iter = arg2.iterator();
    26         while (iter.hasNext())
    27         {
    28             String accessResourceNeedRole = ((SecurityConfig) iter.next())
    29                     .getAttribute();
    30             for (GrantedAuthority grantedAuthority : arg0.getAuthorities())
    31             {
    32                 String userOwnRole = grantedAuthority.getAuthority();
    33                 if (accessResourceNeedRole.equals(userOwnRole))
    34                 {
    35                     return;
    36                 }
    37             }
    38         }
    39         throw new AccessDeniedException("访问被拒绝!");
    40     }
    41 
    42     @Override
    43     public boolean supports(ConfigAttribute arg0)
    44     {
    45         return true;
    46     }
    47 
    48     @Override
    49     public boolean supports(Class<?> arg0)
    50     {
    51         return true;
    52     }
    53 
    54 }

    CustomFilterInvocationSecurityMetadataSource.java

    View Code
     1 package com.spring.security.demo.dependent.components;
     2 
     3 import java.util.ArrayList;
     4 import java.util.Collection;
     5 import java.util.HashMap;
     6 import java.util.Iterator;
     7 import java.util.List;
     8 import java.util.Map;
     9 
    10 import org.springframework.security.access.ConfigAttribute;
    11 import org.springframework.security.access.SecurityConfig;
    12 import org.springframework.security.web.FilterInvocation;
    13 import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
    14 import org.springframework.security.web.util.AntUrlPathMatcher;
    15 import org.springframework.security.web.util.UrlMatcher;
    16 
    17 public class CustomFilterInvocationSecurityMetadataSource implements
    18         FilterInvocationSecurityMetadataSource
    19 {
    20     private Map<String, List<ConfigAttribute>> mp;
    21     private UrlMatcher urlMatcher;
    22 
    23     /**
    24      * 构造每一种资源所需要的角色权限
    25      */
    26     public CustomFilterInvocationSecurityMetadataSource()
    27     {
    28         super();
    29         this.mp = new HashMap<String, List<ConfigAttribute>>();
    30         this.urlMatcher = new AntUrlPathMatcher();
    31         List<ConfigAttribute> list = new ArrayList<ConfigAttribute>();
    32         ConfigAttribute cb = new SecurityConfig("Role_ADMIN"); // 构造一个权限(角色)
    33         ConfigAttribute cbUser = new SecurityConfig("Role_USER"); // 构造一个权限(角色)
    34         ConfigAttribute cbManager = new SecurityConfig("Role_MANAGER"); // 构造一个权限(角色)
    35         list.add(cb);
    36         list.add(cbUser);
    37         list.add(cbManager);
    38         
    39         mp.put("/Main.jsp", list);
    40         list.remove(2);
    41         mp.put("/Main2.jsp", list);
    42     }
    43 
    44     @Override
    45     public Collection<ConfigAttribute> getAllConfigAttributes()
    46     {
    47         return null;
    48     }
    49 
    50     /**
    51      * 获取访问某一个url所需的角色
    52      */
    53     @Override
    54     public Collection<ConfigAttribute> getAttributes(Object arg0)
    55             throws IllegalArgumentException
    56     {
    57         String requestUrl = ((FilterInvocation) arg0).getRequestUrl();
    58         Iterator<String> iter = this.mp.keySet().iterator();
    59         while (iter.hasNext())
    60         {
    61             String temp = iter.next();
    62             if (this.urlMatcher.pathMatchesUrl(requestUrl, temp))
    63             {
    64                 return mp.get(temp);
    65             }
    66         }
    67 
    68         return null;
    69     }
    70 
    71     @Override
    72     public boolean supports(Class<?> arg0)
    73     {
    74         return true;
    75     }
    76 
    77 }

    CustomUserDetailService.java

    View Code
     1 package com.spring.security.demo.dependent.components;
     2 
     3 import java.util.ArrayList;
     4 import java.util.List;
     5 
     6 import org.springframework.dao.DataAccessException;
     7 import org.springframework.security.core.GrantedAuthority;
     8 import org.springframework.security.core.authority.GrantedAuthorityImpl;
     9 import org.springframework.security.core.userdetails.User;
    10 import org.springframework.security.core.userdetails.UserDetails;
    11 import org.springframework.security.core.userdetails.UserDetailsService;
    12 import org.springframework.security.core.userdetails.UsernameNotFoundException;
    13 
    14 public class CustomUserDetailService implements UserDetailsService
    15 {
    16     /**
    17      * arg0 --->登录的用户名
    18      */
    19     @Override
    20     public UserDetails loadUserByUsername(String arg0)
    21             throws UsernameNotFoundException, DataAccessException
    22     {
    23         List<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
    24         GrantedAuthority grantedAuthority = null;
    25 
    26         if ("admin".equals(arg0))
    27         {
    28             grantedAuthority = new GrantedAuthorityImpl("Role_ADMIN");
    29         }
    30         else if ("manager".equals(arg0))
    31         {
    32             grantedAuthority = new GrantedAuthorityImpl("Role_MANAGER");
    33         }
    34         else
    35         {
    36             grantedAuthority = new GrantedAuthorityImpl("Role_USER");
    37         }
    38         grantedAuthorities.add(grantedAuthority);
    39 
    40         User user = new User(arg0, "123456", true, true, true, true,
    41                 grantedAuthorities);
    42 
    43         return user;
    44     }
    45 
    46 }

    三、完成applicationContext-security.xml以及web.xml的配置

    applicationContext-security.xml

    View Code
     1 <beans:beans xmlns="http://www.springframework.org/schema/security"
     2     xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     3     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
     4                         http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
     5     
     6     <!-- 用户验证通过才能授权,若不通过会跳到authentication-failure-url(验证失败页面)
     7           若用户验证通过,但没有default-target-url的访问权限,则会跳转至access-denied-page(授权失败页面) -->
     8     <http access-denied-page="/AccessDenied.jsp">
     9         <intercept-url pattern="/Login.jsp" filters="none" />
    10         <logout logout-success-url="/Login.jsp" />
    11         <form-login login-page="/Login.jsp" default-target-url="/Main.jsp"
    12             authentication-failure-url="/Login.jsp" />
    13         <http-basic />
    14 
    15         <custom-filter ref="CustomSecurityFilter" before="FILTER_SECURITY_INTERCEPTOR" />
    16     </http>
    17 
    18     <beans:bean id="CustomSecurityFilter"
    19         class="com.spring.security.demo.CustomSecurityFilter">
    20 
    21         <!-- 注入决策管理器 -->
    22         <beans:property name="accessDecisionManager" ref="CC_AccessDecisionManager"></beans:property>
    23 
    24         <!-- 注入资源角色授权管理器 -->
    25         <beans:property name="securityMetadataSource" ref="CC_SecurityMetadataSource"></beans:property>
    26 
    27         <!-- 注入身份认证管理器 -->
    28         <beans:property name="authenticationManager" ref="CC_AuthenticationManager"></beans:property>
    29 
    30     </beans:bean>
    31 
    32     <beans:bean id="CC_SecurityMetadataSource"
    33         class="com.spring.security.demo.dependent.components.CustomFilterInvocationSecurityMetadataSource"></beans:bean>
    34 
    35     <beans:bean id="CC_AccessDecisionManager"
    36         class="com.spring.security.demo.dependent.components.CustomAccessDecisionManager"></beans:bean>
    37 
    38     <authentication-manager alias="CC_AuthenticationManager">
    39         <authentication-provider user-service-ref="AidUserDetailService"></authentication-provider>
    40     </authentication-manager>
    41 
    42     <beans:bean id="AidUserDetailService"
    43         class="com.spring.security.demo.dependent.components.CustomUserDetailService"></beans:bean>
    44 </beans:beans>                      

    web.xml

    View Code
     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     3     xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
     4     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
     5     version="3.0">
     6     <listener>
     7         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
     8     </listener>
     9 
    10     <context-param>
    11         <param-name>contextConfigLocation</param-name>
    12         <param-value>/WEB-INF/applicationContext*.xml</param-value>
    13     </context-param>
    14 
    15     <filter>
    16         <filter-name>springSecurityFilterChain</filter-name>
    17         <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    18     </filter>
    19 
    20     <filter-mapping>
    21         <filter-name>springSecurityFilterChain</filter-name>
    22         <url-pattern>/*</url-pattern>
    23     </filter-mapping>
    24 
    25     <display-name></display-name>
    26     <welcome-file-list>
    27         <welcome-file>index.jsp</welcome-file>
    28     </welcome-file-list>
    29 </web-app>

    四、完成前台测试页面

    View Code
     1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
     2 <%
     3 String path = request.getContextPath();
     4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
     5 %>
     6 
     7 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
     8 <html>
     9 <head>
    10 <base href="<%=basePath%>">
    11 
    12 <title>用户登录</title>
    13 
    14 <meta http-equiv="pragma" content="no-cache">
    15 <meta http-equiv="cache-control" content="no-cache">
    16 <meta http-equiv="expires" content="0">
    17 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    18 <meta http-equiv="description" content="This is my page">
    19 <!--
    20     <link rel="stylesheet" type="text/css" href="styles.css">
    21     -->
    22 
    23 </head>
    24 
    25 <body>
    26     <div>
    27         用户名:admin (admin拥有Role_ADMIN角色,其他任意用户拥有Role_USER角色)
    28         密码:123456
    29     </div>
    30     <hr />
    31     <form action="j_spring_security_check" method="POST"> 
    32         用户名:<input type="text" name="j_username" /><br />
    33         密码:<input type="password" name="j_password"><br />
    34         <input type="submit" value="登录">
    35     </form>
    36 </body>
    37 </html>
  • 相关阅读:
    python读取配置文件之.ini后缀文件
    Qt界面中打开图片的一个小bug
    C++指针与数组、函数、动态内存分配
    使用VS调试安卓Unity应用
    VS2017调试Unity时遇到的“未指定错误”解决方法记录
    【5】用vector进行直接插入排序
    【4】数独(Sudoku Killer)(深度优先遍历)
    【3】素数环问题(递归、搜索)
    【2】展开字符串(栈、递归)
    【1】简单计算器(栈)
  • 原文地址:https://www.cnblogs.com/xiongyu/p/2602220.html
Copyright © 2011-2022 走看看