gst*_*low 14 java spring-security oauth-2.0 spring-security-oauth2 spring-oauth2
我有最简单的oauth2客户端:
@EnableAutoConfiguration
@Configuration
@EnableOAuth2Sso
@RestController
public class ClientApplication {
@RequestMapping("/")
public String home(Principal user, HttpServletRequest request, HttpServletResponse response) throws ServletException {
return "Hello " + user.getName();
}
public static void main(String[] args) {
new SpringApplicationBuilder(ClientApplication.class)
.properties("spring.config.name=application").run(args);
}
}
Run Code Online (Sandbox Code Playgroud)
我还有以下内容application.yml:
server:
port: 9999
servlet:
context-path: /client
security:
oauth2:
client:
client-id: acme
client-secret: acmesecret
access-token-uri: http://localhost:8080/oauth/token
user-authorization-uri: http://localhost:8080/oauth/authorize
resource:
user-info-uri: http://localhost:8080/me
logging:
level:
org.springframework.security: DEBUG
org.springframework.web: DEBUG
Run Code Online (Sandbox Code Playgroud)
这是完整的代码.我没有任何其他源代码.它工作正常.
但现在我想添加一个注销功能.我添加了一个端点,但它不起作用.我试着做以下事情:
@RequestMapping("/logout")
public void logout(HttpServletRequest request, HttpServletResponse response) throws ServletException {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
authentication.setAuthenticated(false);
new SecurityContextLogoutHandler().logout(request,response,authentication);
SecurityContextHolder.clearContext();
request.logout();
request.getSession().invalidate();
}
Run Code Online (Sandbox Code Playgroud)
但我仍然登录并可以访问/URL,它用用户名响应我.
你能帮我解决这个问题吗?
我尝试了这里描述的方法https://spring.io/guides/tutorials/spring-boot-oauth2/#_social_login_logout:
@EnableAutoConfiguration
@Configuration
@EnableOAuth2Sso
@Controller
public class ClientApplication extends WebSecurityConfigurerAdapter {
private Logger logger = LoggerFactory.getLogger(ClientApplication.class);
@RequestMapping("/hello")
public String home(Principal user, HttpServletRequest request, HttpServletResponse response, Model model) throws ServletException {
model.addAttribute("name", user.getName());
return "hello";
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http.antMatcher("/**")
.authorizeRequests()
.antMatchers( "/login**", "/webjars/**", "/error**").permitAll()
.anyRequest()
.authenticated()
.and().logout().logoutSuccessUrl("/").permitAll()
.and()
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
// @formatter:on
}
public static void main(String[] args) {
new SpringApplicationBuilder(ClientApplication.class)
.properties("spring.config.name=application").run(args);
}
}
Run Code Online (Sandbox Code Playgroud)
在FE我写道:
<script type="text/javascript">
$.ajaxSetup({
beforeSend: function (xhr, settings) {
if (settings.type == 'POST' || settings.type == 'PUT'
|| settings.type == 'DELETE') {
if (!(/^http:.*/.test(settings.url) || /^https:.*/
.test(settings.url))) {
// Only send the token to relative URLs i.e. locally.
xhr.setRequestHeader("X-XSRF-TOKEN",
Cookies.get('XSRF-TOKEN'));
}
}
}
});
var logout = function () {
$.post("/client/logout", function () {
$("#user").html('');
$(".unauthenticated").show();
$(".authenticated").hide();
});
return true;
};
$(function() {
$("#logoutButton").on("click", function () {
logout();
});
});
</script>
Run Code Online (Sandbox Code Playgroud)
和
<input type="button" id="logoutButton" value="Logout"/>
Run Code Online (Sandbox Code Playgroud)
但它仍然无效.它会导致以下行为:
发布http://localhost:9999/client/logout重定向到http://localhost:9999/client但此页面不存在
gitub上的源代码:
客户端 - https://github.com/gredwhite/logour_social-auth-client(使用localhost:9999/client/hellourl)
服务器 - https://github.com/gredwhite/logout_social-auth-server
将以下代码片段添加到您的 ClientApplication 类中。这也将清除您的会话详细信息。
将以下代码替换为您的 Web 安全适配器类的配置方法。
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/**")
.authorizeRequests()
.antMatchers( "/login**", "/webjars/**", "/error**").permitAll()
.anyRequest()
.authenticated()
.and().logout().invalidateHttpSession(true)
.clearAuthentication(true).logoutSuccessUrl("/login?logout").deleteCookies("JSESSIONID").permitAll().and().csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}
Run Code Online (Sandbox Code Playgroud)
小智 5
您可以从数据库中删除刷新令牌和访问令牌以节省空间。
@PostMapping("/oauth/logout")
public ResponseEntity<String> revoke(HttpServletRequest request) {
try {
String authorization = request.getHeader("Authorization");
if (authorization != null && authorization.contains("Bearer")) {
String tokenValue = authorization.replace("Bearer", "").trim();
OAuth2AccessToken accessToken = tokenStore.readAccessToken(tokenValue);
tokenStore.removeAccessToken(accessToken);
//OAuth2RefreshToken refreshToken = tokenStore.readRefreshToken(tokenValue);
OAuth2RefreshToken refreshToken = accessToken.getRefreshToken();
tokenStore.removeRefreshToken(refreshToken);
}
} catch (Exception e) {
return ResponseEntity.badRequest().body("Invalid access token");
}
return ResponseEntity.ok().body("Access token invalidated successfully");
}
Run Code Online (Sandbox Code Playgroud)
注销的 URL 将是:http://localhost:9999/oauth/logout 此外,在授权标头中传递访问令牌,如
授权:承载0cb72897-c4f7-4f01-aed9-2f3f79a75484
其中,0cb72897-c4f7-4f01-aed9-2f3f79a75484 是访问令牌。
因为,它的 Spring 安全性,不要忘记从授权访问绕过 /oauth/logout url,因为
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/hello", "/oauth/logout");
}
Run Code Online (Sandbox Code Playgroud)
希望,它会解决您在 Springboot2+Oauth2 中的注销问题。它为我工作。
您可能希望使用 Spring Security 对 /logout 端点的内置支持,这将做正确的事情(清除会话并使 cookie 无效)。要配置端点,请扩展 WebSecurityConfigurer 中现有的 configure() 方法:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/**")
.and().logout().logoutSuccessUrl("/").permitAll();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4209 次 |
| 最近记录: |