Spring OAuth2 JWT

  1. 服务注册中心
    主类
    package com.oleka;
    
    import org.springframework.boot.Banner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
    
    @EnableEurekaServer
    @SpringBootApplication
    public class ServiceRegistryApplication {
    
    	public static void main(String[] args) {
    		SpringApplication application = new SpringApplication(ServiceRegistryApplication.class);
    		application.setBannerMode(Banner.Mode.OFF);
    		application.run(args);
    	}
    
    }
    配置
    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:1000/eureka/
        register-with-eureka: false
        fetch-registry: false
    server:
      port: 1000
    spring:
      application:
        name: service-registry
  2. 授权服务器配置
    在主类中创建JwtAccessTokenConverter
    package com.oleka;
    
    import java.security.KeyPair;
    
    import org.springframework.boot.Banner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    import org.springframework.context.annotation.Bean;
    import org.springframework.core.io.ClassPathResource;
    import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
    import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
    import org.springframework.security.oauth2.provider.token.store.KeyStoreKeyFactory;
    
    @SpringBootApplication
    @EnableDiscoveryClient
    @EnableAuthorizationServer
    public class AuthApplication {
    
    	public static void main(String[] args) {
    		SpringApplication application = new SpringApplication(AuthApplication.class);
    		application.setBannerMode(Banner.Mode.OFF);
    		application.run(args);
    	}
    
    	@Bean
    	public JwtAccessTokenConverter accessTokenConverter() {
    		String path = "/keystore.jks", password = "foobar", alias = "test";
    		ClassPathResource resource = new ClassPathResource(path);
    		KeyStoreKeyFactory store = new KeyStoreKeyFactory(resource, password.toCharArray());
    		KeyPair keyPair = store.getKeyPair(alias);
    		JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
    		converter.setKeyPair(keyPair);
    		return converter;
    	}
    
    }
    Spring的自动配置导入OAuth2AuthorizationServerConfiguration
    @Configuration
    @ConditionalOnClass({ OAuth2AccessToken.class, WebMvcConfigurerAdapter.class })
    @Import({ OAuth2AuthorizationServerConfiguration.class,
    		OAuth2MethodSecurityConfiguration.class, OAuth2ResourceServerConfiguration.class,
    		OAuth2RestOperationsConfiguration.class })
    @AutoConfigureBefore(WebMvcAutoConfiguration.class)
    @EnableConfigurationProperties(OAuth2ClientProperties.class)
    public class OAuth2AutoConfiguration {
    
    	private final OAuth2ClientProperties credentials;
    
    	public OAuth2AutoConfiguration(OAuth2ClientProperties credentials) {
    		this.credentials = credentials;
    	}
    
    	@Bean
    	public ResourceServerProperties resourceServerProperties() {
    		return new ResourceServerProperties(this.credentials.getClientId(),
    				this.credentials.getClientSecret());
    	}
    
    }
    OAuth2AuthorizationServerConfiguration找到我们创建的JwtAccessTokenConverter
    	public OAuth2AuthorizationServerConfiguration(BaseClientDetails details,
    			AuthenticationManager authenticationManager,
    			ObjectProvider<TokenStore> tokenStore,
    			ObjectProvider<AccessTokenConverter> tokenConverter,
    			AuthorizationServerProperties properties) {
    		this.details = details;
    		this.authenticationManager = authenticationManager;
    		this.tokenStore = tokenStore.getIfAvailable();
    		this.tokenConverter = tokenConverter.getIfAvailable();
    		this.properties = properties;
    	}
    将tokenConverter设置到AuthorizationServerEndpointsConfiger中
    	@Override
    	public void configure(AuthorizationServerEndpointsConfigurer endpoints)
    			throws Exception {
    		if (this.tokenConverter != null) {
    			endpoints.accessTokenConverter(this.tokenConverter);
    		}
    		if (this.tokenStore != null) {
    			endpoints.tokenStore(this.tokenStore);
    		}
    		if (this.details.getAuthorizedGrantTypes().contains("password")) {
    			endpoints.authenticationManager(this.authenticationManager);
    		}
    	}
    在AuthorizationServerEndpointsConfiger中根据AccessTokenConverter的类型生成对应的tokenStore
    	private TokenStore tokenStore() {
    		if (tokenStore == null) {
    			if (accessTokenConverter() instanceof JwtAccessTokenConverter) {
    				this.tokenStore = new JwtTokenStore((JwtAccessTokenConverter) accessTokenConverter());
    			}
    			else {
    				this.tokenStore = new InMemoryTokenStore();
    			}
    		}
    		return this.tokenStore;
    	}
    在AuthorizationServerEndpointsConfiger中根据AccessTokenConverter的类型决定tokenEnhancer的类型
    	private TokenEnhancer tokenEnhancer() {
    		if (this.tokenEnhancer == null && accessTokenConverter() instanceof JwtAccessTokenConverter) {
    			tokenEnhancer = (TokenEnhancer) accessTokenConverter;
    		}
    		return this.tokenEnhancer;
    	}
    application.yml配置
    logging:
      level:
        root: INFO
        org.springframework.security: DEBUG
        org.springframework.cloud.security: DEBUG
    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:1000/eureka/
    server:
      contextPath: /auth
      port: 8001
    spring:
      application:
        name: auth
    security:
      user:
        password: password
      oauth2:
        authorization:
          tokenKeyAccess: isAuthenticated()
        client:
          clientId: gateway
          clientSecret: 1qaz2wsx123
          scope: nihao
          accessTokenValiditySeconds: 30

  3. 资源服务器配置
    主类
    package com.oleka;
    
    import org.springframework.boot.Banner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
    
    @EnableWebSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    @EnableResourceServer
    @EnableDiscoveryClient
    @SpringBootApplication
    public class TestApplication {
    
    	public static void main(String[] args) {
    		SpringApplication application = new SpringApplication(TestApplication.class);
    		application.setBannerMode(Banner.Mode.OFF);
    		application.run(args);
    	}
    
    }
    配置
    logging:
      level:
        org.springframework.security: DEBUG
        org.springframework.cloud.security: DEBUG
    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:1000/eureka/
    server:
      port: 1001
    spring:
      application:
        name: oleka-test
    security:
      oauth2:
        client:
          clientId: gateway
          clientSecret: 1qaz2wsx123
        resource:
          jwt:
            keyUri: http://localhost:8001/auth/oauth/token_key
    示例controller
    package com.oleka.controller;
    
    import java.util.Date;
    
    import org.springframework.security.access.prepost.PreAuthorize;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @RequestMapping("test")
    public class TestController {
    
    	@GetMapping("test1")
    	@PreAuthorize("hasRole('USER')")
    	public String[] test1() {
    		String[] temp = { "1", "2", new Date().getTime() + "" };
    		return temp;
    	}
    }
  4. 通过Oauth2 Client单点登录
    主类

    package com.oleka;
    
    import org.springframework.boot.Banner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
    
    @EnableZuulProxy
    @EnableOAuth2Sso
    @SpringBootApplication
    @EnableDiscoveryClient
    public class GatewayApplication {
    
    	public static void main(String[] args) {
    		SpringApplication application = new SpringApplication(GatewayApplication.class);
    		application.setBannerMode(Banner.Mode.OFF);
    		application.run(args);
    	}
    
    }
    配置文件
    logging:
      level:
        root: INFO
        org.springframework.security: DEBUG
        org.springframework.cloud.security: DEBUG
    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:1000/eureka/
    server:
      port: 8080
    spring:
      application:
        name: gateway
    security:
      oauth2:
        client:
          clientId: gateway
          clientSecret: 1qaz2wsx123
          scope: nihao
          accessTokenUri: http://localhost:8001/auth/oauth/token
          userAuthorizationUri: http://localhost:8001/auth/oauth/authorize
        resource:
          jwt:
            keyUri: http://localhost:8001/auth/oauth/token_key
  5. 访问http://localhost:8080/oleka-test/test/test1

猜你喜欢

转载自blog.csdn.net/zhang854429783/article/details/80370391