• spring cloud----spring Security


    认证和授权

      认证:登录,验证用户名和密码

      授权:认证通过,给用户加上某些权限,这些权限控制用户是否可以访问资源服务器上哪些资源的资源

    Spring Security

      我们自己实现用户登录过程中,spring MVC,需要自己写拦截器,验证用户是否登录,以及登录接口相关逻辑,当用户登录成功后,把用户信息放到session中等等。这些操作spring Security帮我们都完成了。sprint security提供了用户名和密码登录,退出,会话管理等认证功能,我们需要简单的配置就行。

      spring security给我们提供了要给简单的前台登录页面(用于测试),我们可以写自己的前台页面,然后post请求spring security的后台

    OAuth2

      是一种协议:允许博客(第三方应用)访问微信上存放的我的个人信息,然后用这个信息来登录博客。

      客户端:浏览器,android,ios等

      资源拥有者:通常是用户,可以是应用程序,即资源的拥有者(比如我们自己)。资源拥有者需要通过客户端访问资源。

      授权服务器:(微信),我们自己搭建的授权服务器

      资源服务器:我们自己的服务器

      用户通过客户端访问微信,并且携带client_id(斗地主),让微信给斗地主授权,android拿到授权码,就去微信获取令牌,获取到令牌。就可以通过令牌访问斗地主了。

      用户通过客户端访问自己系统,并且携带client_id(自己的),让自己的授权服务给微博授权,客户端(浏览器)拿到授权码,就去自己授权服务获取令牌,获取到令牌。就可以通过令牌访问自己的资源服务器。

      授权服务和资源服务一般分布式系统是分开的,如果是单体应用,可是可以放到一起的。

      

    Spring MVC+Spring Security

    Spring Boot+Spring Security+jsp

      使用jsp,一定要在spring Boot中配置webapp/WEB-INF

      然后设置prefix和suffix

      spring security逻辑:登录页面post:localhost:port/login,调用loadUserByUsername(),等返回的对象保存到SecurityContextHolder中。结束。

    Spring Boot+SpringCloud+Spring Security+jsp

      略

       

    分析解释

    配置:public void configure(ClientDetailsServiceConfigurer clients)

    //类TokenEndpoint
    @RequestMapping(value = "/oauth/token", method=RequestMethod.POST)
    public ResponseEntity<OAuth2AccessToken> postAccessToken(Principal principal, @RequestParam
    Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
        
            //会去找ClientDetail对象
    	String clientId = getClientId(principal);
    	ClientDetails authenticatedClient = getClientDetailsService().loadClientByClientId(clientId);
    
    }

    配置:authorizedGrantTypes

    clients.inMemory()
            //client模式
            .withClient("client_1")
            .authorizedGrantTypes("client_credentials", "refresh_token")//配置client_1有那些模式

    当访问/oauth/token,会携带一个grant_type,spring security会去我们配置的模式["client_credentials", "refresh_token"]中找,看是否包含test,如果没有就报错,所以我们请求的grant_type必须是我们配置的type中的某一个。

    授权码模式

    说明:code

    code会保存到authorizationCodeStore中【ConcurrentHashMap】

    public class InMemoryAuthorizationCodeServices extends RandomValueAuthorizationCodeServices {
    
    	protected final ConcurrentHashMap<String, OAuth2Authentication> authorizationCodeStore = new ConcurrentHashMap<String, OAuth2Authentication>();
    
    	@Override
    	protected void store(String code, OAuth2Authentication authentication) {
    		this.authorizationCodeStore.put(code, authentication);
    	}
    
    	@Override
    	public OAuth2Authentication remove(String code) {
    		OAuth2Authentication auth = this.authorizationCodeStore.remove(code);
    		return auth;
    	}
    
    }
    

    当调用验证授权码的时候,调用HashMap的remove方法。所以授权码只允许使用一次

    //类RandomValueAuthorizationCodeServices	
    public OAuth2Authentication consumeAuthorizationCode(String code)
    			throws InvalidGrantException {
        OAuth2Authentication auth = this.remove(code);
        if (auth == null) {
            throw new InvalidGrantException("Invalid authorization code: " + code);
        }
        return auth;
    }

    请求/oauth/token,当指定了grant_type="authorization_code",必须传入一个code

    Map<String, String> parameters = tokenRequest.getRequestParameters();
    String authorizationCode = parameters.get("code");
    String redirectUri = parameters.get(OAuth2Utils.REDIRECT_URI);
    
    if (authorizationCode == null) {
      throw new InvalidRequestException("An authorization code must be supplied.");
    }
    

    SecurityContextHolder

      保存用户信息

    SecurityContextHolder.getContext().getAuthentication();
    

    PreAuthorize

      如果需要使用这个注解,需要在任意的@Configuration上添加@EnableGlobalMethodSecurity注解

      @PostAuthorize:调用方法之后拦截

    @Configuration
    @EnableResourceServer
    @EnableGlobalMethodSecurity(prePostEnabled = true)//激活方法上的PreAuthorize注解,如果需要使用@securedEnabled注解,在加上 securedEnabled= true
    public class ResourceServerConfig extends ResourceServerConfigurerAdapter {}

       注解到@Controller方法上

    @PreAuthorize("hasAuthority('course_pic_list')")
    @PreAuthorize("hasAnyAuthority('p1','p2')")
    

    ClientDetailsServiceConfigurer

    //spring-security-oauth2需要配置redirectUris
    //spring-cloud-starter-oauth2 不需要配置redirectUris
    
     clients.inMemory()
                    .withClient("client-a") //client端唯一标识
                    .secret(passwordEncoder.encode("client-a")) //客户端的密码,这里的密码应该是加密后的
                    .authorizedGrantTypes("authorization_code") //授权模式标识
                    .scopes("read_user_info") //作用域
                    .resourceIds("resource1")//资源id
                    .redirectUris("http://localhost:8080/callback"); //回调地址
            // @formatter: on
    

      

  • 相关阅读:
    十七、mysql数据库备份
    消费端ACK和重回队列
    RabbitMQ TTL、死信队列
    消费端限流策略
    029异常处理
    028class_part2
    027class_part1
    026json和pickle,xml模块
    025__name__变量和目录结构规范
    024模块的概念
  • 原文地址:https://www.cnblogs.com/yanxiaoge/p/14213753.html
Copyright © 2020-2023  润新知