第一步引入pom文件:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-jwt</artifactId>
</dependency>
第二步auth配置:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
@Configuration
@EnableAuthorizationServer
public class SsoAuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
/**
* 客户端一些配置
* @param clients
* @throws Exception
*/
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("portal")//服务ID
.secret("secret")//服务密文
.authorizedGrantTypes("authorization_code", "refresh_token")//授权类型
.scopes("all","read","write")//授权范围
.autoApprove(true)
.and()
.withClient("porta2")
.secret("secret")
.authorizedGrantTypes("authorization_code", "refresh_token")
.scopes("all","read","write")
.autoApprove(true)
.and()
.withClient("porta3")
.secret("secret")
.authorizedGrantTypes("authorization_code", "refresh_token")
.scopes("all","read","write")
.autoApprove(true);
}
/**
* 配置jwttokenStore
* @param endpoints
* @throws Exception
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(jwtTokenStore()).accessTokenConverter(jwtAccessTokenConverter());
}
/**
* springSecurity 授权表达式,访问merryyou tokenkey时需要经过认证
* @param security
* @throws Exception
*/
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.tokenKeyAccess("isAuthenticated()");
}
/**
* JWTtokenStore
* @return
*/
@Bean
public TokenStore jwtTokenStore() {
return new JwtTokenStore(jwtAccessTokenConverter());
}
/**
* 生成JTW token
* @return
*/
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter(){
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey("secret");
return converter;
}
}
第三步security设置:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
/**
* spring Security配置
*
*/
@Configuration
public class SsoSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userInfoService;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin().loginPage("/authentication/require")//默认跳转的页面接口
.loginProcessingUrl("/authentication/form")
.and().authorizeRequests()
.antMatchers("/authentication/require",//设置取消安全验证路径
"/authentication/form",
"/**/*.js",
"/**/*.css",
"/**/*.jpg",
"/**/*.png",
"/**/*.woff2"
)
.permitAll()
.anyRequest().authenticated()
.and()
.csrf().disable();
// http.formLogin().and().authorizeRequests().anyRequest().authenticated();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userInfoService);
//.passwordEncoder(passwordEncoder())
}
}
第四步登录前端控制器:
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
/**
* 登录控制器
*
*
*/
@Controller
public class LoginController {
/**
* 跳转到登录页面
*/
@GetMapping("/authentication/require")
public ModelAndView require() {
return new ModelAndView("login");
}
}
第五步页面:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<title>登录界面</title>
<link rel="stylesheet" th:href="@{/css/reset.css}"/>
<link rel="stylesheet" th:href="@{/css/common.css}"/>
<link rel="stylesheet" th:href="@{/css/font-awesome.min.css}"/>
</head>
<body>
<div class="wrap login_wrap">
<div class="content">
<div class="logo"></div>
<div class="login_box">
<div class="login_form">
<div class="login_title">
登录
</div>
<form th:action="@{/authentication/form}" method="post">
<div class="form_text_ipt">
<input name="username" type="text" placeholder="手机号/邮箱" value="admin">
</div>
<div class="ececk_warning"><span>手机号/邮箱不能为空</span></div>
<div class="_warning"><!--<span>${message!''}</span>--></div>
<div class="form_text_ipt">
<input name="password" type="password" placeholder="密码" value="123456">
</div>
<div class="ececk_warning"><span>密码不能为空</span></div>
<div class="form_btn">
<button type="submit">登录</button>
</div>
</form>
</div>
</div>
</div>
</div>
<script type="text/javascript" th:src="@{/js/jquery.min.js}"></script>
<script type="text/javascript" th:src="@{/js/common.js}"></script>
</body>
</html>
第六步集成的服务
pom文件同样引入上边的依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>
security相关配置:
import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@EnableOAuth2Sso
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.headers().frameOptions().disable();
http.csrf().disable();
http
.authorizeRequests()
.antMatchers("**/css/**", "**/fonts/**","**/img/**", "**/js/**", "favicon.ico", "**/plugins/**").permitAll()
.anyRequest().authenticated()
.and()
.logout().logoutUrl("/logout").logoutSuccessUrl("http://10.0.0.224:7000/sso/exit");
}
}
yml文件配置:
#Oauth2.0配置开始
auth-server: http://10.0.0.224:7000/sso #oauth2服务器地址/uaa
security:
oauth2:
client:
client-id: porta3 #security-sample
client-secret: secret #secret
user-authorization-uri: ${auth-server}/oauth/authorize #用户授权证书地址
access-token-uri: ${auth-server}/oauth/token #令牌获取地址
resource:
#user-info-uri: ${auth-server}/user #资源服务提供地址:用户信息获取
jwt:
key-uri: ${auth-server}/oauth/token_key #解析jwt令牌所需要密钥的地址
#Oauth2.0配置结束
这样就可以完成页面请求拦截,跳到安全控制工程;