spring security使用和原理简析(1)

主要参考:https://blog.csdn.net/u012373815/article/details/55225079

源码参考:https://github.com/527515025/springBoot

项目需求

1:实现了用户、角色、权限的动态管理,可以管控到接口地址,已经访问方式(get,post)

2:自定义登录接口

3:结合spring-session,来保存用户登录信息

表结构说明

method来控制相同方法名的不同访问方式(get,post,put等)

项目结构

废话不多说,看一下实现功能的核心代码

SecurityConfig核心方法

  protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                //访问未授权资源的异常,403
                .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
                //登录后访问未配置权限资源的异常,401
                .exceptionHandling().accessDeniedHandler(accessDeniedHandler).and()
                .authorizeRequests()
                //匿名用户也可以访问的资源
                .antMatchers("/api/v1/auth").permitAll()
                .antMatchers("/logout").permitAll()
                .antMatchers("/**","/swagger-resources/**","/translate_a/**","/doc.html", "/webjars/**", "/v2/**", "/META-INF/resources/webjars/","/META-INF/resources/").permitAll()
                .anyRequest().authenticated()
                .and()
                //开启session,同时只能登录一个用户
                .sessionManagement().maximumSessions(1).sessionRegistry(sessionRegistry)
                .and()
                .and()
                .logout().logoutUrl("/api/v1/logout")
                .invalidateHttpSession(true)
                .clearAuthentication(true)
                .and()
                .httpBasic();
    }

UrlFilterSecurityInterceptor核心方法

   @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        FilterInvocation fi = new FilterInvocation(request, response, chain);
        invoke(fi);
    }

    public void invoke(FilterInvocation fi) throws IOException, ServletException {
//fi里面有一个被拦截的url
//里面调用MyInvocationSecurityMetadataSource的getAttributes(Object object)这个方法获取fi对应的所有权限
//再调用MyAccessDecisionManager的decide方法来校验用户的权限是否足够
        InterceptorStatusToken token = super.beforeInvocation(fi);
        try {
//执行下一个拦截器
            fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
        } finally {
            super.afterInvocation(token, null);
        }
    }

UrlAccessDecisionManager核心方法

  public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {

        HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();
        String url, method;
        //关闭鉴权
        if (true){
            return;
        }
        //放行在config中配置的无需登录就能访问的资源
        if ( matchers("/api/v1/auth", request)
                || matchers("/swagger-resources/**", request)
                || matchers("/translate_a/**", request)
                || matchers("/doc.html", request)
                || matchers("/webjars/**", request)
                || matchers("/v2/**", request)
                || matchers("/META-INF/resources/webjars/**", request)
                || matchers("/META-INF/resources/**", request)) {
            return;
        } else {
            //匹配用户所具有的接口访问权限
            for (GrantedAuthority ga : authentication.getAuthorities()) {
                if (ga instanceof UrlGrantedAuthority) {
                    UrlGrantedAuthority urlGrantedAuthority = (UrlGrantedAuthority) ga;
                    url = urlGrantedAuthority.getPermissionUrl();
                    method = urlGrantedAuthority.getMethod();
                    if (matchers(url, request)) {
                        if (method.equals(request.getMethod()) || "ALL".equals(method)) {
                            return;
                        }
                    }
                }
            }
        }
        throw new AccessDeniedException("no right");
    }

登录接口

    @PostMapping("/auth")
    @ApiOperation(value = "用户登录接口")
    public ApiResponse<String> auth(HttpServletRequest request,@RequestBody ReqLoginDto reqLoginDto){
        SysUser user= userService.login(reqLoginDto.getUserName(), reqLoginDto.getPassword());
        //todo 异常捕获,返回错误信息
        if (user==null) {
            return ApiResponse.error("异常","登录异常");
        }

        //加载用户信息及权限
        UserDetails userDetails = customUserService.loadUserByUsername(user.getUsername());
        //生成满足spring security框架要求的登录信息
        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
        authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
        //保存在当前请求的SecurityContextHolder中
        SecurityContextHolder.getContext().setAuthentication(authentication);
        return ApiResponse.ok("success");
    }

完整的项目代码,除了登录可以在https://github.com/527515025/springBoot中的springboot-SpringSecurity3中找到

以上就实现了用户、角色、权限的动态管理,接下来我们简单的探究一下原理

原文地址:https://www.cnblogs.com/jiataoq/p/11073390.html

时间: 2024-11-05 13:26:00

spring security使用和原理简析(1)的相关文章

spring security使用和原理简析(2)

转自https://pjmike.github.io/2018/10/12/%E6%B5%85%E6%9E%90Spring-Security-%E6%A0%B8%E5%BF%83%E7%BB%84%E4%BB%B6/ 上一篇我们主要讲述了如何搭项目,这里我们就来简单探究一下原理 Spring Security的核心类 Spring Security的核心类主要包括以下几个: SecurityContextHolder: 存放身份信息的容器 Authentication: 身份信息的抽象接口 A

Java Annotation 及几个常用开源项目注解原理简析

PDF 版: Java Annotation.pdf, PPT 版:Java Annotation.pptx, Keynote 版:Java Annotation.key 一.Annotation 示例 Override Annotation Java 1 2 3 @Override public void onCreate(Bundle savedInstanceState); Retrofit Annotation Java 1 2 3 @GET("/users/{username}&quo

[转载] Thrift原理简析(JAVA)

转载自http://shift-alt-ctrl.iteye.com/blog/1987416 Apache Thrift是一个跨语言的服务框架,本质上为RPC,同时具有序列化.发序列化机制:当我们开发的service需要开放出去的时候,就会遇到跨语言调用的问题,JAVA语言开发了一个UserService用来提供获取用户信息的服务,如果服务消费端有PHP/Python/C++等,我们不可能为所有的语言都适配出相应的调用方式,有时候我们会很无奈的使用Http来作为访问协议;但是如果服务消费端不能

cgroup原理简析:进程调度

本篇来探究下cgroup对cpu的限制机制,前文提到过cgroup也是通过进程调度子系统来达到限制cpu的目的,因此需要了解下进程调度子系统. 因为是介绍cgroup的文章,因此只介绍进程调度中与cgroup密切关联的部分,详细完成的进程调度实现可参考进程调度的相关资料. 本文分为三个部分,首先介绍进程调度中的调度算法,在该基础上引入组调度,最后结合前面文章(cgroup原理简析:vfs文件系统)来说明上层通过echo pid >> tasks, echo n > cpu.shares等

Java Android 注解(Annotation) 及几个常用开源项目注解原理简析

不少开源库(ButterKnife.Retrofit.ActiveAndroid等等)都用到了注解的方式来简化代码提高开发效率. 本文简单介绍下 Annotation 示例.概念及作用.分类.自定义.解析,并对几个 Android 开源库 Annotation 原理进行简析.PDF 版: Java Annotation.pdf, PPT 版:Java Annotation.pptx, Keynote 版:Java Annotation.key 完整版原文见:Java Android 注解(Ann

SIFT特征原理简析(HELU版)

SIFT(Scale-Invariant Feature Transform)是一种具有尺度不变性和光照不变性的特征描述子,也同时是一套特征提取的理论,首次由D. G. Lowe于2004年以<Distinctive Image Features from Scale-Invariant Keypoints[J]>发表于IJCV中.开源算法库OpenCV中进行了实现.扩展和使用. 本文主要依据原始论文和网络上相关专业分析,对SIFT特征提取的算法流程进行简单分析.由于涉及到的知识概念较多,本人

Spring Security入门(2-2)Spring Security 的运行原理 2

Java配置和表单登录 因此使用Java代码配置Spring Security主要是这两个步骤:1.创建过滤器2.注册过滤器. 1.创建过滤器这段配置创建一个Servlet Filter:springSecurityFilterChain,其负责应用中的所有安全,包括:保护应用的URLS,验证提交的username和password,重定向到登录页面等. 通过以下代码可以看到使用Java配置Spring Security的基础案例: @EnableWebSecuritypublic class

ARP攻击原理简析及防御措施

0x1  简介 网络欺骗攻击作为一种非常专业化的攻击手段,给网络安全管理者,带来严峻的考验.网络安全的战场已经从互联网蔓延到用户内部的网络, 特别是局域网.目前利用ARP欺骗的木马病毒在局域网中广泛传播,导致网络随机掉线甚至整体瘫痪,通讯被窃听,信息被篡改等严重后果. 0x2  ARP协议概述 ARP协议(address resolution protocol)地址解析协议 一台主机和另一台主机通信,要知道目标的IP地址,但是在局域网中传输数据的网卡却不能直接识别IP地址,所以用ARP解析协议将

iOS Block原理简析

Block的语法 Block是iOS闭包的实现方式,能够获取局部变量的匿名函数. Block的OC声明 返回值类型 (^Block变量名字)(参数列表) = (参数列表){}; 例子 int (^add)(int a,int b) = ^(int a, int b) { return a + b; }; int sum = add(1,4); NSLog(@"sum = %d",sum); NSString* (^getFullName)(NSString *first,NSStrin