因为leader要求在搭好的spring cloud 框架中加入对微服务的认证包括单点登陆认证,来确保系统的安全,因此研究了Spring Cloud Security这个组件。在前面搭好的demo中,如何确保微服务的安全,为整个系统添加安全控制,就须要用到Spring Cloud Security。用户经过服务网关zuul来访问任何一个微服务的时候,都须要跳转到第三方的认证好比github或者本身搭好的CAS单点登陆服务,当认证经过才能访问对应的服务。在研究spring cloud security 以前先对一些概念进行了解了。
OAuth2(重点),参考文档:http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html
Spring Security OAuth2,参考文档:http://docs.spring.io/spring-boot/docs/1.5.2.RELEASE/reference/htmlsingle/#boot-features-security-oauth2
html
在这个文章中主要记录当用户经过服务网关zuul入口访问任何一个微服务。须要先跳转到GitHub,使用Github进行认证,认证经过以后才能跳转到访问咱们提供的微服务。git
(1) 前往https://github.com/settings/developers
,点击“Register a new application”按钮,添加一个应用。点击按钮后,界面以下图所示。Homepage URL 和callback url是写zuul的端口。
(2) 点击“Register application”按钮,便可出现以下图的界面。
记住这边的Client ID以及Client Secret,后面有用。
至此,准备工做就完成了。github
代码测试成功以后的Github地址:https://github.com/LoveIpo/spring-cloud-demo/tree/master/Zuul_CAS
这个Zuul_CAS是在zuul中进一步完善!spring
在这里,咱们正式进行编码。由于我是在服务网关zuul中添加单点登陆的服务认证受权。因此对前面demo中的zuul 工程进一步完善。
(1) 在pom.xml文件为应用添加spring-cloud-starter-oauth二、spring-cloud-starter-security两个依赖。api
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zuul</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-oauth2</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-security</artifactId> </dependency> </dependencies>
(2) 在zuul的启动类中添加以下代码安全
@SpringBootApplication @EnableZuulProxy @RestController public class GatewayApplication { public static void main(String[] args) { SpringApplication.run(GatewayApplication.class, args); } @GetMapping("/") public String welcome() { return "welcome"; } @RequestMapping("/user") public Principal user(Principal user) { return user; } @Component @EnableOAuth2Sso // 实现基于OAuth2的单点登陆,建议跟踪进代码阅读如下该注解的注释,颇有用 public static class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http. antMatcher("/**") // 全部请求都得通过认证和受权 .authorizeRequests().anyRequest().authenticated() .and().authorizeRequests().antMatchers("/","/anon").permitAll() .and() // 这里之因此要禁用csrf,是为了方便。 // 不然,退出连接必需要发送一个post请求,请求还得带csrf token // 那样我还得写一个界面,发送post请求 .csrf().disable() // 退出的URL是/logout .logout().logoutUrl("/logout").permitAll() // 退出成功后,跳转到/路径。 .logoutSuccessUrl("/login"); } } }
如代码所示,在这里,咱们使用@EnableOAuth2Sso 注解,启用了“基于OAuth2的单点登陆”,作了一些安全配置;同时,还定义了两个端点,/ 端点返回“welcome”字符串,/user 端点返回当前登陆用户的认证信息。session
这里说明一下,@EnableOAuth2Sso注解。若是WebSecurityConfigurerAdapter类上注释了@EnableOAuth2Sso注解,那么将会添加身份验证过滤器和身份验证入口。若是只有一个@EnableOAuth2Sso注解没有编写在WebSecurityConfigurerAdapter上,那么它将会为全部路径启用安全,而且会在基于HTTP Basic认证的安全链以前被添加。详见@EnableOAuth2Sso的注释。
(3) 修改zuul 的application.yml文件,部分代码以下app
server: port: 7073 security: user: password: user # 直接登陆时的密码 ignored: / sessions: never # session策略 oauth2: sso: loginPath: /login # 登陆路径 client: clientId: 你的clientId clientSecret: 你的clientSecret accessTokenUri: https://github.com/login/oauth/access_token userAuthorizationUri: https://github.com/login/oauth/authorize resource: userInfoUri: https://api.github.com/user preferTokenInfo: false spring: application: name: zuul eureka: client: serviceUrl: defaultZone: http://localhost:7071/eureka/
这样,经过服务网关zuul来访问任何一个服务都要跳转到github进行认证的主要代码就编写完成了。框架
(1) 启动Eureka、zuul、serviceA
(2) 当经过服务网关zuul(端口7073) 访问serviceA 的url:http://localhost:7073/api-a/add?a=111&b=113
时。页面会自动跳转到github进行认证。
你也能够经过zuul访问serviceB也会自动跳转到github进行认证以后才能回调到serviceB。
(3) 当输入github的用户名和密码认证经过以后,会出现serviceA的调用结果。以下图所示
(4) 当你认证经过以后输入http://localhost:7073/user
能够看到你github 的用户信息。ide