gpt4 book ai didi

How can I invalidate the jwt token after logout in Spring Boot with Spring Security(如何在带有Spring Security的Spring Boot中注销后使JWT令牌无效)

转载 作者:bug小助手 更新时间:2023-10-25 10:00:32 27 4
gpt4 key购买 nike



I tried to implement an example with the usage of jwt token in Spring Boot. It covers register, login, refresh token and lastly logout process. I have a problem in logout process.

我试图通过在Spring Boot中使用JWT令牌来实现一个示例。它包括注册、登录、刷新令牌和最后的注销过程。我在注销过程中遇到问题。


I tried to delete jwt token after logout but I think the process of invalidating the jwt token is the best way to handle with this process.

我试图在注销后删除JWT令牌,但我认为使JWT令牌无效的过程是处理此过程的最佳方式。


Here is the logout method of auth service shown below

下面是auth服务的注销方法如下所示


Here is the logout request shown below

以下是如下所示的注销请求


@Data
@AllArgsConstructor
@NoArgsConstructor
public class LogoutRequest {

private String token;
}

Here is the logout method of controller

以下是控制器的注销方法


@PostMapping("/logout")
public ResponseEntity<String> logout(@RequestBody LogoutRequest request) {

return ResponseEntity.ok(authService.logout(request));
}

Here is the getIdFromToken shown below

下面是如下所示的getIdFromToken


public Long getIdFromToken(String token){
return Long.parseLong(extractClaims(token).getId());
}

Here is deleteByUserId shown below

下面是如下所示的DeleteByUserID


@Override
public int deleteByUserId(Long userId) {

User user = userService.findById(userId).orElseThrow(() -> new RuntimeException("User not found"));
return refreshTokenRepository.deleteByUser(user);
}

How can I do that?

我怎么能做到这一点?


Here is the repo : Link

以下是回购:链接


更多回答

Does this answer your question? Java Spring cannot logout properly

这回答了你的问题吗Java Spring无法正常注销

i looked at your filter, your filter does nothing except validate the signage of the token. If you provide a token, how does your filter know that the token has been "invalidated", well it doesnt? The funny thing here is that you are reimplementing session authentication using JWTs, why dont you just use session cookies?

我查看了您的筛选器,您的筛选器除了验证令牌的签名外,什么也不做。如果您提供了令牌,您的筛选器如何知道令牌已经“失效”,但它没有呢?有趣的是,您正在使用JWT重新实现会话身份验证,为什么不直接使用会话Cookie呢?

@K.Nicholas is he using auth0 i can't see that, this entire application looks like some home built own custom insecure authentication service by someone that doesnt know what FormLogin is, and he is rebuilding FormLogin from scratch but insisting on using JWTs instead of cookies which means he is loosing the benefits like httpOnly Securedand same-site

@K.Nicholas他在使用Auth0吗我看不出来,这整个应用程序看起来像是某个不知道FormLogin是什么的人自己定制的不安全身份验证服务,他正在从头开始重建FormLogin,但坚持使用JWTs而不是Cookie,这意味着他正在失去HttpOnly Secured和Same-Site等好处

he doesnt have an issuer, the github he has provided he has built his own login and issues a jwt by himself github.com/Rapter1990/bookdelivery/blob/… so basically he has done the same misstake as everyone else, he is using JWT as a session. Most likely just found some poor tutorial saying that you should use JWTs as sessions

他没有发行者,他提供的GitHub他已经建立了自己的登录并由他自己发行了JWT/githeb.com/Rapter1990/bookDelivery/Blob/…因此,基本上他和其他人一样做了错误的赌注,他正在使用JWT作为一个会话。很可能只是找到了一些糟糕的教程,说您应该使用JWTs作为会话

so the answer here is basically, he is using JWTs the wrong way and, he is using them as sessions which you should not. You dont use JWTs when you build this type of login because of the simple reason. You can not invalidate a JWT without either rotating the keys which invalidates all JWTs issued, or as he is trying to do, build a some sort of database to keep track of the issued JWTs, which means he needs to check in his filter everytime someone supplies a JWT if the JWT is logged out or not, which he currently doesnt. So his login endpoint does nothing, and his filter will gladly let them in

所以这里的答案基本上是,他在以错误的方式使用JWTs,他将它们用作您不应该使用的会议。在构建这种类型的登录时,您不使用JWTs,原因很简单。您不能在不旋转密钥的情况下使JWT无效,这会使发布的所有JWT失效,或者像他试图做的那样,构建某种类型的数据库来跟踪发布的JWT,这意味着每次有人提供JWT时,他都需要签入他的过滤器,如果JWT已经注销或没有注销的话,他目前还没有这样做。因此,他的登录端点什么也不做,而他的过滤器会很乐意地让他们进入

优秀答案推荐

So the answer here is the following:

因此,这里的答案如下:


What you have here is you have built a login, that at successful login you create your JWT in your service and hand out a token directly to the calling client. This is in oauth2 called an implicit flowand was deprecated from the oauth2 rfc because it was found to be insecure.

这里你已经构建了一个登录,在成功登录时,你在你的服务中创建了你的JWT,并直接向调用客户端分发了一个令牌。这在oauth2中被称为隐式流,并从oauth2 rfc中被弃用,因为它被发现是不安全的。


You also have built some sort of custom solution with some sort of thing you call a refresh token, which basically stores an id in some sort of storage.

您还使用所谓的刷新令牌构建了某种定制解决方案,该令牌基本上将ID存储在某种存储中。


So in principal, what you have actually built is some sort of Session authentication containing state, but completely custom, using JWTs.

因此,从原则上讲,您实际构建的是某种包含状态的会话身份验证,但完全是使用JWT定制的。


You have tried to reinvent something that already exists in Spring Security which is called FormLogin which basically does all the things you want the only difference is that FormLogin uses cookies (which has additional security features like httpOnly, Secured, and same-site) but with JWTs.

您试图重新发明Spring Security中已有的东西,称为FormLogin,它基本上可以做您想做的所有事情,唯一的区别是FormLogin使用Cookie(它具有额外的安全特性,如HTTPOnly、Secure和Same-Site),但带有JWTs。


So you are ending up with the same thing as FormLogin just less secure.

因此,您最终得到的是与FormLogin相同的东西,只是安全性较低。


"Logging out" a JWT isn't really possible. You can only invalidate a JWT by letting it time out. Once a JWT is created with and expiration date is set and then signed, its signed. The contract has been written.

“注销”JWT是不可能的。您只能通过让JWT超时来使其无效。一旦使用创建了JWT,并设置了到期日期,然后对其进行签名,它就会被签名。合同已经写好了。


The problem with your code is that when someone supplies a JWT to your application is that your filter that checks the JWTs just checks if the signage and expiration is still valid.

代码的问题是,当有人向您的应用程序提供JWT时,检查JWT的过滤器只检查标志和过期是否仍然有效。


// Checking the validity and expiration
Jwts.parserBuilder()
.setSigningKey(getSignInKey())
.build()
.parseClaimsJws(authToken);

As long is the signage and time stamp is still valid your JWT will pass through here:

只要标志和时间戳仍然有效,您的JWT就会从这里通过:


if (jwt != null && jwtUtils.validateJwtToken(jwt)) {
// some other code
}

Which means you never check if the token is actually logged out in your custom refreshToken database, so the filter never understands that anything is logged out.

这意味着您永远不会检查令牌是否已在您的自定义刷新标记数据库中注销,因此筛选器永远不会知道有任何东西已注销。


So you need to do a check here, but remember, you will then in each request done to your service, you have to possibly do 2 database calls. One to check if the token isnt logged out, and a second one to check if the user exists and log them in. Thats 2 database calls for every request, unless you store things in memory, or offload using caches etc.

因此,您需要在这里进行检查,但请记住,在对您的服务完成的每个请求中,您可能需要进行2次数据库调用。一个用于检查令牌是否未注销,另一个用于检查用户是否存在并让他们登录。对于每个请求,这是2个数据库调用,除非您将内容存储在内存中,或者使用缓存等进行卸载。


The bottom line is that, you are basically trying to build FormLogin using JWTs, but less secure and possibly with less good performance and i strongly discourage you from doing so.

归根结底,您基本上是在尝试使用JWTs构建FormLogin,但安全性较差,性能可能也较差,我强烈建议您不要这么做。



You just can't invalidate a JWT.

您只是不能使JWT无效。


What you can invalidate, are the sessions on the OAuth2 authorization server (which delivered the token) and OAuth2 client (to which the token was delivered).

您可以使之无效的是OAuth2授权服务器(传递令牌)和OAuth2客户端(令牌被传递到的)上的会话。


Spring Security client implementation can be configured to do both: perform logout from the authorization server with a post-logout handler on the client.

Spring Security客户端实现可以配置为同时执行这两种操作:在客户机上使用注销后处理程序从授权服务器执行注销。


The thing is that apparently, the application configuration and flows used have nothing to do with OAuth2, which ends to something pretty unsafe and inefficient as pointed in the other answer. You should just trash all that and opt for:

问题是,显然,使用的应用程序配置和流与OAuth2无关,正如另一个答案中指出的那样,OAuth2以一些非常不安全和低效的东西结束。你应该把所有这些都扔掉,选择:



  • formLogin (with sessions and CSRF protection) if you don't need externalized authentication (SSO with the rest of your information system) or secured inter micro-services calls

  • proper OAuth2 otherwise (with confidential client on your server)


更多回答

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com