SSO Server
前期准备:
使用maven构建项目,导入1.5.4SpringBoot父jar包
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
<relativePath/>
</parent>
导入所必须的springboot集成security的jar包spring-boot-starter-security以及它的依赖包spring-security-jwt
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-jwt</artifactId>
基于OAuth认证,导入
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
由于是web项目继续导入spring-boot-starter-web
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
页面显示模版使用springBoot官方推荐的thymeleaf 导入spring-boot-starter-thymeleaf
使用Java工具包中的keytool制作证书serverKeystore.jks,设置别名为alias1,密码为123456
命令:keytool -genkey -alias alias1 -keyalg RSA -keysize 1024 -keystore serverKeystore.jks -validity 365
将证书放入resource文件夹
编码:
一:新建OAuthConfigurer.java继承AuthorizationServerConfigurerAdapter,实现该类所有方法,该类为OAuth认证配置类
1.配置客户端认证方式以及客户端连接参数设置:
public void configure(ClientDetailsServiceConfigurer clients)
throws Exception {
clients.inMemory()
//该配置为SSO客户端配置所需的
client-id: acme;client-secret: acmesecret
.withClient("acme").secret("acmesecret")
.authorizedGrantTypes("authorization_code", "refresh_token").scopes("openid");
}
2.配置oauth认证安全策略 从表单提交经过OAuth认证
public void configure(AuthorizationServerSecurityConfigurer security)
throws Exception {
security.tokenKeyAccess("permitAll()").checkTokenAccess(
"isAuthenticated()").allowFormAuthenticationForClients();
}
3.认证转换器配置使用@Bean的方式注入到当前方法中
首先实现一个方法加上@Bean注解交给IOC容器管理这个Bean,在该方法中设置之前放置证书的路径以及设置的别名和密码,set到Jwt认证转换器中,并返回一个转换器
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter(){
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
KeyPair keyPair = new KeyStoreKeyFactory(new ClassPathResource("serverKeystore.jks"), "123456".toCharArray()).getKeyPair("alias1");
converter.setKeyPair(keyPair);
return converter;
}
之后注入到认证转换器配置中调用
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints.accessTokenConverter(jwtAccessTokenConverter());
}
最后在该类上加上@Configuration注解,表明这是一个beans上下文配置Spring容器,加上@EnableAuthorizationServer注解开启Auth认证服务器
二:新建类SecurityConfiguration继承WebSecurityConfigurerAdapter 配置认证管理器,以及安全策略
①配置认证管理器(AuthenticationManagerBuilder):
两种方式:
1. 配置固定用户名密码
auth.inMemoryAuthentication()
.withUser("user") //用户名
.password("user")//密码
.roles("USER")//角色
2. 通过实现userDetailsService接口类重写loadUserByUsername()方法返回UserDetails进行密码匹配
auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder());
auth.eraseCredentials(false);
该密码加密方式为Springsecurity推荐的加密方式,放弃之前的PasswordEncoder改用BCryptPasswordEncoder()
②配置安全策略(HttpSecurity)
http
//关闭csrf
//.csrf().disable()
//取消安全报文头 默认开启 可配置部分开启或全关
//.headers().disable()
//登录页面url 配置登录成功后调用的方法
.formLogin().loginPage("/login").permitAll().successHandler(loginSuccessHandler())
.and().csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).and()
.authorizeRequests()
//配置这些链接无需验证
.antMatchers("/regist","/toregist").permitAll()
//除以上路径都需要验证
.anyRequest().authenticated()
//路径角色验证
//.antMatchers("/admin/**").hasRole("ADMIN")
//排除该路径角色认证 注意顺序自上而下
//.antMatchers("/**").hasRole("USER")
.and()
//注销登录 默认支持 销毁session并且清空配置的rememberMe()认证 跳转登录页 或配置的注销成功页面
.logout()
.deleteCookies("remove")
.invalidateHttpSession(false)
.logoutUrl("/logout")
.logoutSuccessUrl("/logoutsuccess")
.and()
//http参数中包含一个名为“remember-me”的参数,不管session是否过期,用户记录将会被记保存下来
.rememberMe()
//.and()
////http映射https
//.portMapper()
//.http(8080).mapsTo(9443)
.and()
//配置http认证
.httpBasic()
.and()
//当用户进行重复登录时 强制销毁前一个登录用户 配置此应用必须添加Listener HttpSessionEventPublisher
.sessionManagement()
.maximumSessions(1)
.expiredUrl("/login?expired");
三:编写SecurityUser类继承当前User类并且实现UserDetails接口
在构造方法中塞入需要返回给客户端的权限信息
四:编写CustomUserDetailsService类实现UserDetailsService接口
实现loadUserByUsername()方法将传入的用户名进行数据查询,并返回经过SecurityUser包装的UserDetails对象
五:根据需要新建LoginSuccessHandler类继承SavedRequestAwareAuthenticationSuccessHandler
重写onAuthenticationSuccess()方法,通过安全策略配置登录成功后调用该类,用作记录登录时间等日志信息