Spring Sercurity权限控制(一)

学生程序设计能力提升平台 Spring Sercurity的应用

Spring security的使用

spring security 的核心功能主要包括:

  • 认证 (你是谁)
  • 授权 (你能干什么)
  • 攻击防护 (防止伪造身份)

其核心就是一组过滤器链,项目启动后将会自动配置。最核心的就是 Basic Authentication Filter 用来认证用户的身份,一个在spring security中一种过滤器处理一种认证方式。

Configration-http/https

首先继承WebSecurityConfigurerAdapter重写configure

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //授权
        http.authorizeRequests()
                .antMatchers("/user/login", "/user/admin/login", "/user/register", "/user/logout").permitAll()
                .anyRequest().authenticated()
                .and().csrf().disable()  //CSRF禁用,因为不使用session
                .sessionManagement().disable()  //禁用session
                .formLogin().disable() //禁用form登录
                .cors()
                .and()
                .addFilterAfter(new OptionsRequestFilter(), CorsFilter.class)
                //添加登录filter
                .apply(new JsonLoginConfig<>())
                .loginSuccessHandler(usernameLoginSuccessHandler())
                .and()
                //添加token的filter
                .apply(new JwtLoginConfig<>())
                .tokenValidSuccessHandler(jwtRefreshSuccessHandler())
                .permissiveRequestUrls("/logout")
                .and()
                //使用默认的logoutFilter
                .logout()
                .logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler()) //logout成功后返回200
                .and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

分析项目中的代码

  1. 允许未经授权即可访问的接口

    http.authorizeRequests()
                    .antMatchers("/user/login", "/user/admin/login", "/user/register", "/user/logout").permitAll()
    

    这一段代码允许了所有不经过SpringSercurity即可访问访问的接口,包含登录,注册等。利用登录注册的过程是本省就不要任何权限就能做的。

  2. .anyRequest().authenticated()标明除此上一段代码排除的白名单外所有的接口均是需要鉴权的

  3. 禁用csrf以及session

    and().csrf().disable()  //CSRF禁用,因为不使用session
                    .sessionManagement().disable()  //禁用session
                    .formLogin().disable() //禁用form登录
    

    这里禁用CSRF的愿意是因为没有使用session因此不会存留cookie在本地,那么项目使用什么来鉴别神的的呢,我们下面再谈

Configration-cors

在web网页开发中最长见到的问题就是cors问题,跨域资源问题,网页和服务器几乎不能出现在统一ip的同一端口上,因此是必要运训cors,对于资源服务器,可能只允许固定的ip访问,但是对于应用服务器应该允许所有的ip访问服务器

  1. 这一行标记使用spring sercurity的corshttp.authorizeRequests().cors()

  2. 我们查看SpringSercurity源码

    cors使用的方法是调用了getOrApply方法新建了一个CorsConfigurer

    	public CorsConfigurer<HttpSecurity> cors() throws Exception {
    		return getOrApply(new CorsConfigurer<>());
    	}
    

    getOrApply()方法主要是应用配置,而通过new CorsConfigurer<>()发现只是一个空的构造函数也不是我们需要的

    接着我们来看getOrApply()方法

    private <C extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity>> C getOrApply(C configurer) throws Exception {
    		C existingConfig = (C) getConfigurer(configurer.getClass());
    		if (existingConfig != null) {
    			return existingConfig;
    		}
    		return apply(configurer);
    	}
    

    首先该方法调用getConfigurer()尝试获取系统中已经存在的configerer

    	public <C extends SecurityConfigurer<O, B>> C getConfigurer(Class<C> clazz) {
    		List<SecurityConfigurer<O, B>> configs = this.configurers.get(clazz);
    		if (configs == null) {
    			return null;
    		}
    		Assert.state(configs.size() == 1,
    				() -> "Only one configurer expected for type " + clazz + ", but got " + configs);
    		return (C) configs.get(0);
    	}
    

    调用getConfigurer()方会从configs中获取cors的配置,可以看出SpringSercurity并没有对cors做特殊处理,只是给返回加上了可以cors的请求方式

    另外注意.addFilterAfter(new OptionsRequestFilter(), CorsFilter.class)是必须的SpringSercurity会在调用cors之前调用一次Options请求

    public class OptionsRequestFilter extends OncePerRequestFilter {
        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
                throws ServletException, IOException {
            if (request.getMethod().equals("OPTIONS")) {
                response.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,HEAD");
                response.setHeader("Access-Control-Allow-Headers", response.getHeader("Access-Control-Request-Headers"));
                return;
            }
            filterChain.doFilter(request, response);
        }
    
    }
    

    cors由统一的拦截器配置,在项目中利用了filter+bean+config的方式实现

    	@Bean
        CorsConfigurationSource corsConfigurationSource() {
            CorsConfiguration configuration = new CorsConfiguration().applyPermitDefaultValues();
            configuration.addExposedHeader("Authorization");
            UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            source.registerCorsConfiguration("/**", configuration);
            return source;
        }
    

    利用@Bean注入Cors配置

    首先初始化默认的操作,接着统一配置暴漏的响应头,最后设置所有的接口均被配置来实现所有的接口均能够通过跨域请求访问

Configuration-login/logout

SpringSecurity自带的登录活注销界面,虽然比较美观,但是往往是不符合实际需求的,因此需要额外的定制登录或者注册接口

.apply(new JsonLoginConfig<>())
                .loginSuccessHandler(usernameLoginSuccessHandler())
                .and()
                //添加token的filter
                .apply(new JwtLoginConfig<>())
                .tokenValidSuccessHandler(jwtRefreshSuccessHandler())
                .permissiveRequestUrls("/logout")
                .and()
                //使用默认的logoutFilter
                .logout()
                .logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler()); //logout成功后返回200

项目中使用两种不同的登录方式,通过用户名密码登录,或者是用过token直接登录,那么就需要根据不同的情况进行不同的配置

image-20211007152533404

退出登录的是否依然是通过鉴权链,将携带的token加入到黑名单数据库中实现token的失效

登录成功的请求将会根据登录的验证返回颁发合法的json web token签名,实现登录功能

登录成功之后会出发handler,handler将角色信息和身份信息一并写入token中,并返回签证的token

public class UsernameLoginSuccessHandler implements AuthenticationSuccessHandler {


    public UsernameLoginSuccessHandler() { }

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
                                        Authentication authentication) {
        //生成token,并把token加密相关信息缓存
        //生成以','分割的角色信息
        String roles = authentication.getAuthorities().stream()
                .map(Object::toString).collect(Collectors.joining(","));
        String token = JwtUtil.createToken(authentication.getName(), ((PtaUser) authentication.getPrincipal()).getUserId(), roles);
        response.setHeader("Authorization","Bearer " + token);
        response.setCharacterEncoding("UTF-8");
        try {
            response.getWriter().print(JSON.toJSONString(ResultEntity.data(token)));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
我们可以使用Spring Security来实现权限认证,以确保系统的安全性。 答案:SpringSecurity权限认证是一种基于Java的安全框架,旨在为企业应用程序提供安全保护。它提供了认证和授权功能,可以帮助您管理用户访问应用程序的安全性。Spring Security 是一个基于 Spring 框架的安全框架,用于保护 Spring 应用程序中的 Web 资源。它提供了一系列的安全服务,包括认证、授权、攻击防护等功能,能够帮助开发者构建安全性强的应用程序。 Spring Security权限认证可以通过多种方式来实现,例如:基于数据库、LDAP、OAuth2、OpenID 等多种认证方式。同时,Spring Security 也支持基于角色的权限控制,可以通过配置角色、权限等信息来实现对用户访问资源的控制。 在 Spring Security 中,可以通过编写配置类、注解等方式来实现权限认证。开发者可\u4ee5\u4e0b\u662f\u7ffb\u8bd1\u4e3a\u4e0a\u6587\u7684\u82f1\u6587\u7248\u672c: Question: Spring Security权限认证,你的回答是:我们可以使用Spring Security来实现权限认证,以确保系统的安全性。 Answer: Spring Security权限认证是一种基于Java的安全框架,旨在为企业应用程序提供安全保护。它提供了认证和授权功能,可以帮助您管理用户访问应用程序的安全性。Spring Security是一个基于Spring框架的安全框架,用于保护Spring应用程序中的Web资源。它提供了一系列的安全服务,包括认证、授权、攻击防护等功能,能够帮助开发者构建安全性强的应用程序。 Spring Security权限认证可以通过多种方式来实现,例如基于数据库、LDAP、OAuth2、OpenID等多种认证方式。同时,Spring Security也支持基于角色的权限控制,可以通过配置角色、权限等信息来实现对用户访问资源的控制。 在Spring Security中,可以通过编写配置类、注解等方式来实现权限认证。开发者可以根据自己的需求来选择不同的方式来实现权限认证。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值