spring cloud security oauth2单点登录
1.maven依赖关系
pom.xml中添加
<!--身份验证服务器>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
<dependency> <groupId>org.springframework.security.oauth</groupId> <artifactId>spring-security-oauth2</artifactId> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
2.客户端应用程序的安全配置
/** * spring boot 启动类 */ @EnableFeignClients // 注册和发现服务 // 需要设置 eureka.client.serviceUrl.defaultZone @EnableDiscoveryClient // 断路由 // 开启 hystrix 支持 必须启用此注解 @EnableCircuitBreaker @EnableOAuth2Sso @SpringBootApplication public class AdminWebApplication extends WebSecurityConfigurerAdapter { public static void main(String[] args) { SpringApplication.run(AdminWebApplication.class, args); } @Override public void configure(HttpSecurity http) throws Exception { // @formatter:off http.logout().logoutSuccessUrl("/").and().authorizeRequests().anyRequest() .authenticated().and().csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()); // @formatter:on } @Override public void configure(WebSecurity web) throws Exception { web.ignoring().antMatchers("/userInfo.xhtml"); } }
3.application.yml
server: port: ${service.server.port:9091} session: cookie: domain: ifa.com spring: application: name: admin-web devtools: restart: enabled: true aop: proxy-target-class: true security: oauth2: sso: login-path: /login.xhtml client: client-id: channel client-secret: b8a9cb1c-cc63-4999-8702-983d246c2d66 access-token-uri: http://passport.auth.com/oauth/token #URI获取访问令牌 user-authorization-uri: http://passport.auth.com/oauth/authorize #授权的URI,用户将被重定向到 client-authentication-scheme: form scope: app resource: user-info-uri: http://passport.auth.com/userInfo #用户端点的URI来获得当前用户详细信息
4.oauth配置
* */ package com.ifa.cloud.channel; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.netflix.feign.EnableFeignClients; @EnableFeignClients //注册和发现服务 //需要设置 eureka.client.serviceUrl.defaultZone @EnableDiscoveryClient //断路由 //开启 hystrix 支持 必须启用此注解 @EnableCircuitBreaker @SpringBootApplication public class SSOWebApplication { public static void main(String[] args) { SpringApplication.run(SSOWebApplication.class, args); } }
5.配置授权服务器
package com.ifa.cloud.channel.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.oauth2.authserver.AuthorizationServerProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
import com.ifa.cloud.channel.config.oauth2.ClientDetailsServiceImpl;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Configuration
@EnableResourceServer
@EnableAuthorizationServer
@EnableConfigurationProperties(AuthorizationServerProperties.class)
public class Oauth2ServerConfig extends AuthorizationServerConfigurerAdapter{
@Bean
public ResourceServerConfigurer resourceServerConfigurer() {
return new ResourceServerConfigurer() {
@Override
public void configure(HttpSecurity http) throws Exception {
log.debug("loadding resource server configurer http ...");
http.antMatcher("/userInfo").authorizeRequests()
.anyRequest().authenticated();
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
}
};
}
@Autowired
public RedisConnectionFactory redisConnectionFactory;
@Bean
public TokenStore tokenStore() {
log.debug("loadding redis token store ...");
return new RedisTokenStore(redisConnectionFactory);
}
@Bean
public ClientDetailsService clientDetailsService() {
return new ClientDetailsServiceImpl();
}
private final AuthenticationManager authenticationManager;
private final AuthorizationServerProperties properties;
public Oauth2ServerConfig(AuthenticationManager authenticationManager,AuthorizationServerProperties properties) {
this.authenticationManager = authenticationManager;
this.properties = properties;
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(clientDetailsService());
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints.tokenStore(tokenStore());
endpoints.authenticationManager(this.authenticationManager);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security)
throws Exception {
if (this.properties.getCheckTokenAccess() != null) {
security.checkTokenAccess(this.properties.getCheckTokenAccess());
}
if (this.properties.getTokenKeyAccess() != null) {
security.tokenKeyAccess(this.properties.getTokenKeyAccess());
}
if (this.properties.getRealm() != null) {
security.realm(this.properties.getRealm());
}
security.allowFormAuthenticationForClients();
}
}
6.安全配置
/** * */ package com.ifa.cloud.channel.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @Configuration @Order(-20) public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private AuthenticationManager authenticationManager; @Override protected void configure(HttpSecurity http) throws Exception { // @formatter:off http .formLogin().loginPage("/login.html").failureUrl("/login.html?error").defaultSuccessUrl("/").usernameParameter("username") .passwordParameter("password").permitAll() .and() .requestMatchers().antMatchers("/login.html", "/oauth/authorize", "/oauth/confirm_access") .and() //除以上路径都需要验证 .authorizeRequests().anyRequest().authenticated(); // @formatter:on // http.authorizeRequests().antMatchers("/oauth/token").anonymous().antMatchers("/login.html").permitAll() // .antMatchers("/**").authenticated().and().httpBasic().and().formLogin().loginPage("/login.html") // .failureUrl("/login.html?error").defaultSuccessUrl("/").usernameParameter("username") // .passwordParameter("password").and().sessionManagement() // .sessionCreationPolicy(SessionCreationPolicy.NEVER); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(authenticationProvider).parentAuthenticationManager(authenticationManager); //auth.inMemoryAuthentication().withUser("admin").password("admin").roles("USER").and().withUser("user") // .password("user").roles("USER"); } @Override public void configure(WebSecurity web) throws Exception { web.ignoring().antMatchers("/style/**", "/script/**", "/font-awesome/**", "/fonts/**", "/webjars/**"); } @Autowired private AuthenticationProvider authenticationProvider; }
7.用户终端
/** * */ package com.ifa.cloud.channel.web.controller; import java.security.Principal; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.ModelAndView; import lombok.extern.slf4j.Slf4j; @Slf4j @RestController public class UserLoginController { @RequestMapping("/login.html") public ModelAndView login(HttpServletRequest request,HttpServletResponse response) { return new ModelAndView("login"); } @RequestMapping("/userInfo") public Object userinfo(Principal principal) { return principal; } }
返回的JSON表示的用户数据。