目录标题

  • 1.授权认证
  • 1.1 定义
  • 1.2.实现
  • 1.2.1 授权登录接口
  • 1.2.2 授权回调接口
  • 1.2.3 过滤器链
  • 1.2.3 过滤器配置
  • 2.权限管理
  • 2.1 接口权限
  • 2.2 菜单权限


1.授权认证

1.1 定义

这里是通过spring security实现了 SSO单点登录认证
具体步骤就是:
1.客户端 收到了登录请求(“/login”),带上回调地址等信息,直接跳转至 第三方登陆页面
2.用户在 第三方登陆页面 输入账户、密码
3.第三方登陆页面 访问 客户端 给的回调地址(传参包括 授权码)
4.客户端 根据授权码等信息,调用 第三方登录系统 获取令牌的接口,获取Token
5.客户端将Token添加到cookie中,并返回给前端

之后前端的每次操作都会带上Token,而客户端也会解析Token,从而获取用户的信息,并把用户信息更新到SecurityContext (安全上下文)中。

1.2.实现

1.2.1 授权登录接口

@ReqestMapping("/login")
public String login(HttpServletRequest request ,HttpServletResponse  response){
	//拼接第三方登录接口的url:url本身 +  param
	//param包括项目信息、指定返回url......



	//这里用到了springboot快捷的重定向方式(返回后会自动帮我们重定向到url去) 
	return "redirect:url";
	
}

1.2.2 授权回调接口

@ReqestMapping("/login-callback")
public String login(HttpServletRequest request ,HttpServletResponse  response,String state ,String code , String returnUri){
	//校验state (不接这个参数也可以,用的话也是用来防止CSRF攻击的)

	//将授权码等作为param,调取 第三方获取Token的接口,获取Token,将Token放到cookie中,然后返回给前端


	//这里用到了springboot快捷的重定向方式(返回后会自动帮我们重定向到指定的url中) 
	return "redirect:"+ returnUri;	
}

1.2.3 过滤器链

既然是用了 spring security 技术,那肯定是涉及到 过滤器链了。下面举例:
这里的FIlter顺序为:ExceptionHandlerFilter–> Filter1 —>…

//用于捕获过滤器链在执行中产生的异常,所以要放在最前面
//这里用的过滤器和平常见到的大同小异
@Component
public class ExceptionHandlerFilter  exetends OncePerRequestFilter {

	@override
	public void doFilterInternal(HttpServletRequest request , HttpServletResponse response ,FilterChain filterChain) {
		try{
			filterChain.dochain(request,response);
		}catch(Exception e){
			//异常处理
		}
	}

}



// 获取用户信息
public class Filter1 exetends OncePerRequestFilter {

	@override
	public void doFilterInternal(HttpServletRequest request , HttpServletResponse response ,FilterChain filterChain) {
		//从header或cookie中拿取Token
		//解析Token,获取用户信息
		//用户信息保存到SecurityContext(安全上下文中)
		filterChain.dochain(request,response);
	}

}

1.2.3 过滤器配置

通过spring security的 WebSecurityConfigurerAdapter配置过滤器链

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

	@Resource
    private Filter1  filter1;
    
    @Resource
    private ExceptionHandlerFilter exceptionHandlerFilter;

    static {
        // 允许子线程拿到父线程的鉴权信息
        SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = http.authorizeRequests();
        registry.anyRequest().authenticated();
        //关闭跨域请求验证
        registry.and().csrf().disable();
        //添加过滤器
        registry.and()
        	.addFilterBefore(filter2, UsernamePasswordAuthenticationFilter.class)
        	.addFilterBefore(exceptionHandlerFilter, CorsFilter.class);
    }
}

2.权限管理

权限管理的最好方式就是给用户们,设置几个不同的角色,根据角色来确定用户的权限。
而我们所指的权限一般指两种:接口、菜单

2.1 接口权限

创建一张角色和接口的关系表

role

auth

admin

[GET]/me

admin

[GET]/list

admin

[POST]/buy

user

[GET]/me

temp_user

[GET]/me

由上表可以看出,管理员admin拥有3个接口的权限,而user、temp_user只有1个接口的权限。
至于如何编写提供项目所有接口的代码,可以自行百度。

2.2 菜单权限

创建一张角色和菜单的关系表

role

menu

admin

goods

admin

orders

admin

news

user

goods

temp_user

goods

由上表可以看出,管理员admin拥有3个菜单的权限,而user、temp_user只有goods菜单的权限。
我们只需要给前端提供这些信息,剩余操作由前端完成。