zoukankan      html  css  js  c++  java
  • Spring Security 学习+实践

    Spring Security是Spring为解决应用安全所提供的一个全面的安全性解决方案。基于Spring AOP和Servlet过滤器,启动时在Spring上下文中注入了一组安全应用的Bean,并在应用开发中提供了声明式的安全访问控制功能,使开发者可以在请求级和方法级上处理用户身份认证与鉴权,大大减少了应用开发安全处理时编写代码的工作量。

    接下来通过代码来实践一番,首先在pom中添加security的依赖:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>

    添加依赖后启动服务,可以看到控制台打印如下信息:

    当Spring Security启动时,如果没有指定用户服务则会创建一个默认的用户,登录名称为user,5392bb9d-0673-4a9f-ab1a-c07522c84c5f是登录口令。

    这时如果我们通过postman去请求,会返回如下结果:

     按照默认的认证方式传递用户名和密码即可成功请求获取返回值,如下图所示:

    如果通过浏览器访问,则会自动跳转到默认的登录页面:

    通过上述测试,我们对Spring Security能实现的效果有了一个直观的感受。但是在实际应用场景中,认证的方式是需要开发人员自己来实现的,那么如何让Spring Security使用我们所定义的用户名和登录口令呢?

    @Configuration
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Bean
        @Override
        public UserDetailsService userDetailsServiceBean() throws Exception {
            return super.userDetailsServiceBean();
        }
    
        @Bean
        @Override
        public AuthenticationManager authenticationManagerBean() throws Exception {
            return super.authenticationManagerBean();
        }
    
        @Override
        protected void configure(AuthenticationManagerBuilder authManagerBuilder) throws Exception {
            authManagerBuilder.inMemoryAuthentication().withUser("eddy").password("123456").roles("user");
        }
    }

    在上面的代码实现中继承了WebSecurityConfigurerAdapter并使用其所提供的默认配置,通过覆写configure()方法,以内存的方式增加应用用户信息的定义。在增加的用户中我们设置了用户的登录名、登录口令及相应的用户权限(角色)。

    这时我们重新启动服务,由于已经指定了认证规则,在控制台也不会打印随机生成的口令了。这时我们通过postman再去请求,发现服务端抛出了如下异常:

    java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
    	at org.springframework.security.crypto.password.DelegatingPasswordEncoder$UnmappedIdPasswordEncoder.matches(DelegatingPasswordEncoder.java:244) ~[spring-security-core-5.1.13.RELEASE.jar:5.1.13.RELEASE]
    	at org.springframework.security.crypto.password.DelegatingPasswordEncoder.matches(DelegatingPasswordEncoder.java:198) ~[spring-security-core-5.1.13.RELEASE.jar:5.1.13.RELEASE]
    	at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$LazyPasswordEncoder.matches(WebSecurityConfigurerAdapter.java:605) ~[spring-security-config-5.1.13.RELEASE.jar:5.1.13.RELEASE]
    	at org.springframework.security.authentication.dao.DaoAuthenticationProvider.additionalAuthenticationChecks(DaoAuthenticationProvider.java:90) ~[spring-security-core-5.1.13.RELEASE.jar:5.1.13.RELEASE]
    	at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:166) ~[spring-security-core-5.1.13.RELEASE.jar:5.1.13.RELEASE]
    	at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:175) ~[spring-security-core-5.1.13.RELEASE.jar:5.1.13.RELEASE]
    	at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:200) ~[spring-security-core-5.1.13.RELEASE.jar:5.1.13.RELEASE]
    	at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:180) ~[spring-security-web-5.1.13.RELEASE.jar:5.1.13.RELEASE]

    经过查阅资料,了解到Spring security 5.0中新增了多种加密方式,使得当进行验证时Spring Security将传输的数据看作是进行了加密后的数据,在匹配之后发现找不到正确识别序列,就认为id是null,因此要将前端传过来的密码进行某种方式加密。

    修改后的代码如下:
    @Override
    protected void configure(AuthenticationManagerBuilder authManagerBuilder) throws Exception {
        authManagerBuilder.inMemoryAuthentication()
                .passwordEncoder(new BCryptPasswordEncoder())
                .withUser("eddy")
                .password(new BCryptPasswordEncoder().encode("123456"))
                .roles("user");
    }

    再次测试,成功返回!

     
    参考资料:
    《Spring Cloud微服务架构开发实战》
    https://www.jianshu.com/p/796c10c3381a
  • 相关阅读:
    docker运行jar包
    jQuery动态添加元素并绑定事件
    Ubuntu将软件(Sublime Text 2为例)锁定到启动器
    jQuery实现列表自动滚动
    浅谈css中的position属性
    关于jQuery中.attr()和.prop()的问题
    Python_opencv库
    Python_faker (伪装者)创建假数据
    Python_Tips_dumpload 和 dumpsloads 的区别与联系
    Linux_CentOS 7下Nginx服务器的安装配置
  • 原文地址:https://www.cnblogs.com/xuzichao/p/15346876.html
Copyright © 2011-2022 走看看