乐趣区

Spring-Cloud-Spring-Security实践一-基本概念及实践

基本使用

Spring security 需要的基本依赖:

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

其他部分不需要任何的增加。

Security 的理论是两个核心:认证(我是谁)和鉴权(我能做什么)。
在 code 中,这两个核心都需要通过继承 WebSecurityConfigurerAdapter 来实现。

➡️废话不多说,上代码

首先,确保 yml 中添加了上面提到的两个依赖。添加后这就是最基本的 spring security 工程了。

然后,我们可以先添加一些 controller。比如 IndexController

@RestController
public class IndexController{@RequestMapping(value = "/", method = RequestMethod.GET)
    public String index(){return "index";}
}

此时启动项目,会发现启动 log 中夹杂着一句乱码:

Using generated security password: 2465a939-a37d-4d3e-9ee1-05d2e51f18fb

这个“乱码”就是 spring security 提供的缺省密码。
此时访问项目 url,会自动跳转到项目 url/login 页面。

默认 username 为 user, password 栏输入刚刚那一句“乱码”。
点击 signin,发现跳转成功,会访问到我们最初访问的页面。

自定义用户名密码

创建@configuration:

新建一个类,继承 WebSecurityConfigurerAdapter, 添加注解 @EnableWebSecurity(不用再添加@Configuration 注解,因为已被 EnableWebSecurity 包含)如下所示。

@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {}

覆写父类方法:

覆写 configure(AuthenticationManagerBuilder auth) 方法
⚠️ 父类中包含多个 configure 方法,注意选择正确方法。代码如下所示:

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
            .withUser("user").password(new BCryptPasswordEncoder().encode("123")).roles("USER");
}

此方法实现了三个功能:

  1. 定义了用户名和密码(user/123)
  2. 加密了密码 – ⚠️ springsecurity 强制密码加密,此处必须这样写
  3. 定义此用户的 role 为 USER – Spring security 根据 role 来做鉴权操作,此处只是认证,暂时忽视即可。

此时,重启项目,已经看不到最开始那一串乱码了,使用 user/123 登陆,即可跳转至正确页面。

鉴权

覆写方法
鉴权依靠的是另一个方法:configure(HttpSecurity http),代码如下:

@Override
    protected void configure(HttpSecurity http) throws Exception {}

示例代码及注释如下:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
         // 匹配 "/","/index" 路径,不需要权限即可访问
        .antMatchers("/user/user1").permitAll()
         // 匹配 "/admin" 及其以下所有路径,都需要 "USER" 权限
        .antMatchers("/admin/**").hasRole("USER")
        .and()
        // 登录地址为 "/login",登录成功默认跳转到页面 "/user"
        .formLogin().loginPage("/login").defaultSuccessUrl("/user/user1")
        .and()
        // 退出登录的地址为 "/logout",退出成功后跳转到页面 "/login"
        .logout().logoutUrl("/logout").logoutSuccessUrl("/login");
}
退出移动版