SpringSecurity

一.概念

1.认证

认证是为了保护系统的隐私数据与资源,用户的身份合法方可访问该系统的资源。

用户认证就是判断一个用户的身份是否合法的过程,用户去访问系统资源时系统要求验证用户的身份信息,身份合法方可继续访问,不合法则拒绝访问。

2.会话

  用户认证通过后,为了避免用户的每次操作都进行认证可将用户的信息保证在会话中。会话就是系统为了保持当前用户的登录状态所提供的机制,常见的有基于 session 方式、基于 token 方式等。

基于 session 的认证方式如下图:

它的交互流程是,用户认证成功后,在服务端生成用户相关的数据保存在 session (当前会话)中,发给客户端的 sesssion_id 存放到 cookie 中,这样用户客户端请求时带上 session_id 就可以验证服务器端是否存在 session 数据,以此完成用户的合法校验,当用户退出系统或 session 过期销毁时,客户端的 session_id 也就无效了。

基于token方式如下图:

它的交互流程是,用户认证成功后,服务端生成一个 token 发给客户端,客户端可以放到 cookie 或 localStorage 等存储中,每次请求时带上 token,服务端收到token通过验证后即可确认用户身份。

基于 session 的认证方式由 Servlet 规范定制,服务端要存储 session 信息需要占用内存资源,客户端需要支持 cookie;基于 token 的方式则一般不需要服务端存储 token,并且不限制客户端的存储方式。如今移动互联网时代更多类型的客户端需要接入系统,系统多是采用前后端分离的架构进行实现,所以基于 token 的方式更适合。

3.授权

授权是用户认证通过根据用户的权限来控制用户访问资源的过程,拥有资源的访问权限则正常访问,没有权限则拒绝访问。

授权的数据模型

授权可简单理解为Who对What(which)进行How操作,包括如下:

Who,即主体(Subject),主体一般是指用户,也可以是程序,需要访问系统中的资源。 What,即资源(Resource),如系统菜单、页面、按钮、代码方法、系统商品信息、系统订单信息等。系统菜单、页面、按钮、代码方法都属于系统功能资源,对于web系统每个功能资源通常对应一个URL;系统商品信息、系统订单信息都属于实体资源(数据资源),实体资源由资源类型和资源实例组成,比如商品信息为资源类型,商品编号 为001的商品为资源实例。How,权限/许可(Permission),规定了用户对资源的操作许可,权限离开资源没有意义,如用户查询权限、用户添加权限、某个代码方法的调用权限、编号为001的用户的修改权限等,通过权限可知用户对哪些资源都有哪些操作许可。

主体、资源、权限相关的数据模型如下:

主体(用户id、账号、密码、…)

权限(权限id、权限标识、权限名称、资源名称、资源访问地址、…)

角色(角色id、角色名称、…)

角色和权限关系(角色 id、权限id、…)

主体(用户)和角色关系(用户id、角色id、…)

4.RBAC

1)基于角色的访问控制

  RBAC基于角色的访问控制(Role-Based Access Control)是按角色进行授权,比如:主体的角色为总经理可以查询企业运营报表,查询员工工资信息等,访问控制流程如下:

2)基于资源的访问控制

 按资源进行授权(Resource-Based Access Controller)

5.基于Session的认证方式

  基于 Session 认证方式的流程是,用户认证成功后,在服务端生成用户相关的数据保存在 session (当前会话),而发给客户端的 sesssion_id 存放到 cookie 中,这样用客户端请求时带上 session_id 就可以验证服务器端是否存在 session 数据,以此完成用户的合法校验。当用户退出系统或 session 过期销毁时,客户端的 session_id 也就无效了。

下图是 session 认证方式的流程图:

基于 Session 的认证机制由 Servlet 规范定制,Servlet 容器已实现,用户通过 HttpSession 的操作方法即可实现,如下是 HttpSession 相关的操作 API 。

方法

含义

HttpSession getSession(Boolean create)

获取当前HttpSession对象

void setAttribute(String name,Object value)

向session中存放对象

object getAttribute(String name)

从session中获取对象

void removeAttribute(String name)

移除session中对象

void invalidate()

使HttpSession失效

二.使用 Spring Security

1.什么是Spring Security

Spring 是非常流行和成功的 Java 应用开发框架,Spring Security 正是 Spring 家族中的成员。Spring Security 基于 Spring 框架,提供了一套 Web 应用安全性的完整解决方案。

SpringSecurity的核心功能:

用户认证(Authentication):系统判断用户是否能登录

用户授权(Authorization):系统判断用户是否有权限去做某些事情

SpringSecurity 特点:

Spring 技术栈的组成部分,与Spring 无缝整合。

全面的权限控制,能提供完整可扩展的认证和授权支持保护

专门为 Web 开发而设计。

重量级,需要引入各种家族组件与依赖

2.使用SpringSecurity

1)创建springboot项目

引入jir包

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

2)创建测试类

3)访问

访问主页会被拦截 , 登录后放行

默认账号为user

默认密码在后端控制台

登录后 访问成功

3.自定义用户名和密码

1)在配置文件设置用户信息

spring.security.user.name=test
spring.security.user.password=123456

登录

访问成功

2)在内存中定义用户信息

package com.example.demo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    /**
     * AuthenticationManagerBuilder  认证管理器的构建者
     * @param auth
     * @throws Exception
     */
//    @Override
//    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        //  UserDeatils
//        UserDetails user = User.withDefaultPasswordEncoder() // 默认不支持明文密码    加密   使用默认的加密方式
//                .username("test")  //  用户名   user
//                .password("123456")// 密码   123456
//                .roles("USER")
//                .build();
//        auth.inMemoryAuthentication()  // inMemoryAuthentication  内存 // 将用户的信息 存放到内存里面
//                .withUser(user);//  user
//    }


    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // dgjsgfhgfwkhsabvksghsgksgkws -> 123456
        //bCryptPasswordEncoder.encode("123456") == dgjsgfhgfwkhsabvksghsgksgkws




        //不支持 明文
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String encode = bCryptPasswordEncoder.encode("123456");
        System.out.println(encode);
        auth.inMemoryAuthentication()
                .passwordEncoder(bCryptPasswordEncoder)
             .withUser("test")
             .password(encode)
             .roles("USER");
    }
}

或者

也可以储存多个用户

登录成功

4.自定义页面

1)创建login页面

<form action="/test" method="post">
用户名:<input type="text" name="myname">
<br/>
用户名:<input type="password" name="mypwd">
<br/>
<input type="submit" value="login">
</form>

注意 请求方法为post

2)修改配置类

     //自定义登录
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //配置登录表单   路径前必须加  "/"
        http.formLogin().loginPage("/login.html")//登录的页面
                .loginProcessingUrl("/test")
                .defaultSuccessUrl("/test");//默认路径
//                .usernameParameter("myname")   .passwordParameter("mypwd")  //自定义密码和账号
        http.authorizeHttpRequests().antMatchers("/login.html","/userlogin","/").permitAll();//表示放行
        //除了以上三个路径其他的路径都需要认证
        http.authorizeHttpRequests().anyRequest().authenticated();
        //csrf  方便html文件通过
        http.csrf().disable();
    }

登录页面改变

参数

表示配置资源信息的时候角色一定是以ROLE_为开始的

5.使用注解

1)修改启动类

@EnableGlobalMethodSecurity(securedEnabled=true,prePostEnabled = true,jsr250Enabled=true)

2)判断是否有对象

@Secured({"ROLE_admin"})
@RequestMapping("testSecured")
public String testSecured() {
return "testSecured";
}

 

表示用户拥有ROLE_ADMIN角色时才允许访问

以上方法是将用户信息存储到内存中

6.自定义实现类完成登录

1)实现 UserDetailsService 接口

2)获取用户信息

3)操作

BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String encode = passwordEncoder.encode("123456");
TabUser tabUser= new TabUser("admin1",encode);
if(username.equals(tabUser.getUsername())){
    List<SimpleGrantedAuthority> authorities = new ArrayList<>();
    // authorities  代表的是所有的资源的信息
    // 菜单   角色
    // 如果是角色  ROLE_
    // 菜单 随便写
    authorities.add(new SimpleGrantedAuthority("testpath"));// 菜单
    authorities.add(new SimpleGrantedAuthority("ROLE_USER"));// 角色
    return new User(username,encode,authorities);
}

4)修改配置文件

@Resource
private UserDetailsService userDetailsService;
    @Bean
    public PasswordEncoder getPassword(){
        return new BCryptPasswordEncoder();
    }
    // 自定义用户的信息
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(getPassword());
    }

  • 12
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值