zoukankan      html  css  js  c++  java
  • Spring Security-利用URL地址进行权限控制

    目的是:系统内存在很多不同的用户,每个用户具有不同的资源访问权限,具体表现就是某个用户对于某个URL是无权限访问的。需要Spring Security忙我们过滤。

    本文的很多命名都是参考链接博文的,最大的不同应该是本文是基于Spring boot,再次也向前人致敬!

    由上一篇可知,FilterSecurityInterceptor是Spring Security进行URL权限判断的,FilterSecurityInterceptor又继承于AbstractSecurityInterceptor,由此可推测,我们可以新增一个Interceptor继承AbstractSecurityInterceptor,实现我们自己的权限校验逻辑。

    查看父类及其代码逻辑,有几点必须要注意:
    1、主要鉴权方法是调用父类中accessDecisionManager的decide值,所以我们需要自己实现一个accessDecisionManager
    2、父类中存在抽象方法public abstract SecurityMetadataSource obtainSecurityMetadataSource();作用是获取URL及用户角色对应的关系。我们需要加入自己的实现。

    以下是部分代码实现
    主要拦截器JwtUrlSecurityInterceptor,需要在WebSecurityConfig(Spring Security配置)文件中注册
    1. //这个拦截器用来实现按照用户权限,对所请求的url进行拦截
    2. @Bean
    3. public JwtUrlSecurityInterceptor jwtUrlSecurityInterceptorBean() throws Exception{
    4. return new JwtUrlSecurityInterceptor();
    5. }
    6. @Override
    7. protected void configure(HttpSecurity httpSecurity) throws Exception {
    8. ...
    9. httpSecurity.addFilterBefore(jwtUrlSecurityInterceptorBean(), FilterSecurityInterceptor.class);
    10. ...
    11. }
    实现自定义的accessDecisionManager
    1. package org.zerhusen.security.dsuri;
    2. import org.springframework.security.access.AccessDecisionManager;
    3. import org.springframework.security.access.AccessDeniedException;
    4. import org.springframework.security.access.ConfigAttribute;
    5. import org.springframework.security.authentication.InsufficientAuthenticationException;
    6. import org.springframework.security.core.Authentication;
    7. import java.util.Collection;
    8. /**
    9. * Created by dingshuo on 2017/6/28.
    10. */
    11. public class MyAccessDecisionManager implements AccessDecisionManager {
    12. @Override
    13. public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {
    14. System.out.println("自定义的接口");
    15. throw new AccessDeniedException("no right");
    16. }
    17. @Override
    18. public boolean supports(ConfigAttribute attribute) {
    19. return true;
    20. }
    21. @Override
    22. public boolean supports(Class<?> clazz) {
    23. return true;
    24. }
    25. }
    实现自定义的资源SecurityMetadataSource 
    1. package org.zerhusen.security.dsuri;
    2. import org.springframework.beans.factory.annotation.Autowired;
    3. import org.springframework.security.access.ConfigAttribute;
    4. import org.springframework.security.access.SecurityConfig;
    5. import org.springframework.security.web.FilterInvocation;
    6. import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
    7. import java.util.*;
    8. /**
    9. * Created by dingshuo on 2017/6/28.
    10. */
    11. public class MyInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
    12. private static Map<String, Collection<ConfigAttribute>> resourceMap = null;
    13. @Autowired
    14. UrlMatcher urlMatcher;
    15. public MyInvocationSecurityMetadataSource() {
    16. //这里可以查数据库实现
    17. //注入dao即可
    18. resourceMap = new HashMap<String, Collection<ConfigAttribute>>();
    19. Collection<ConfigAttribute> atts = new ArrayList<ConfigAttribute>();
    20. ConfigAttribute ca = new SecurityConfig("ROLE_USER1");
    21. atts.add(ca);
    22. resourceMap.put("/index.jsp", atts);
    23. Collection<ConfigAttribute> attsno =new ArrayList<ConfigAttribute>();
    24. ConfigAttribute cano = new SecurityConfig("ROLE_NO");
    25. attsno.add(cano);
    26. resourceMap.put("/other.jsp", attsno);
    27. }
    28. @Override
    29. public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
    30. String url = ((FilterInvocation)object).getRequestUrl();
    31. Iterator<String> ite = resourceMap.keySet().iterator();
    32. while (ite.hasNext()) {
    33. String resURL = ite.next();
    34. if (url.equals("/protected")) {
    35. return resourceMap.get(resURL);
    36. }
    37. }
    38. return null;
    39. }
    40. @Override
    41. public Collection<ConfigAttribute> getAllConfigAttributes() {
    42. return null;
    43. }
    44. @Override
    45. public boolean supports(Class<?> clazz) {
    46. return true;
    47. }
    48. }
    实现JwtUrlSecurityInterceptor
    1. package org.zerhusen.security.dsuri;
    2. import org.springframework.beans.factory.annotation.Autowired;
    3. import org.springframework.context.annotation.Bean;
    4. import org.springframework.security.access.AccessDecisionManager;
    5. import org.springframework.security.access.SecurityMetadataSource;
    6. import org.springframework.security.access.intercept.AbstractSecurityInterceptor;
    7. import org.springframework.security.access.intercept.InterceptorStatusToken;
    8. import org.springframework.security.authentication.AuthenticationManager;
    9. import org.springframework.security.web.FilterInvocation;
    10. import javax.servlet.*;
    11. import java.io.IOException;
    12. /**
    13. * Created by dingshuo on 2017/6/28.
    14. */
    15. public class JwtUrlSecurityInterceptor extends AbstractSecurityInterceptor implements
    16. Filter {
    17. @Autowired
    18. public void setMyAccessDecisionManager(){
    19. super.setAccessDecisionManager(myAccessDecisionManagerBean());
    20. }
    21. @Bean
    22. public MyAccessDecisionManager myAccessDecisionManagerBean(){
    23. return new MyAccessDecisionManager();
    24. }
    25. @Bean
    26. public MyInvocationSecurityMetadataSource myInvocationSecurityMetadataSourceBean(){
    27. return new MyInvocationSecurityMetadataSource();
    28. }
    29. @Override
    30. public void init(FilterConfig filterConfig) throws ServletException {
    31. }
    32. @Override
    33. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    34. FilterInvocation fi = new FilterInvocation(request, response, chain);
    35. invoke(fi);
    36. }
    37. @Override
    38. public void destroy() {
    39. }
    40. @Override
    41. public Class<?> getSecureObjectClass() {
    42. return FilterInvocation.class;
    43. }
    44. @Override
    45. public SecurityMetadataSource obtainSecurityMetadataSource() {
    46. return this.myInvocationSecurityMetadataSourceBean();
    47. }
    48. public void invoke(FilterInvocation fi) throws IOException, ServletException {
    49. InterceptorStatusToken token = super.beforeInvocation(fi);
    50. try {
    51. fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
    52. }finally {
    53. super.afterInvocation(token, null);
    54. }
    55. }
    56. }
    如上是简单的URL权限控制
  • 相关阅读:
    QQ下面功能移动效果
    网页中选择功能
    自定义listview
    android的内存优化分析【转,超级推荐】
    animation的xml定义中的android:interpolator属性(转)
    HOME键与Notification配合使用的bug重现【原创】
    (转载)Android下Affinities和Task(开发者指南)
    职场加薪步步高升的五大法则(转)
    强引用,软引用和弱引用。
    更改字体的ttf。
  • 原文地址:https://www.cnblogs.com/tilv37/p/7094935.html
Copyright © 2011-2022 走看看