使用 Spring 安全注册创建会话
Posted
技术标签:
【中文标题】使用 Spring 安全注册创建会话【英文标题】:session create using spring security registration 【发布时间】:2020-06-08 01:24:28 【问题描述】:我正在使用构建https://github.com/Baeldung/spring-security-registration 的文章之后的spring security 进行注册处理。根据本文,html
页面接受输入并将其插入到数据库中。
我正在前端使用 Flutter 应用程序。我希望当用户请求重置密码时,会向用户的电子邮件发送一个链接,当用户单击验证链接时,它将创建一个会话并重定向到应用程序上的 UI 页面编写新密码。当用户输入新密码时,它将更新该用户的密码。
updatePassword.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css"/>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"/>
<style>
.password-verdict
color:#000;
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script th:src="@/resources/pwstrength.js"></script>
<title th:text="#message.updatePassword">update password</title>
</head>
<body>
<div sec:authorize="hasAuthority('CHANGE_PASSWORD_PRIVILEGE')">
<div class="container">
<div class="row">
<h1 th:text="#message.resetYourPassword">reset</h1>
<form>
<br/>
<label class="col-sm-2" th:text="#label.user.password">password</label>
<span class="col-sm-5"><input class="form-control" id="password" name="newPassword" type="password"
value=""/></span>
<div class="col-sm-12"></div>
<br/><br/>
<label class="col-sm-2" th:text="#label.user.confirmPass">confirm</label>
<span class="col-sm-5"><input class="form-control" id="matchPassword" type="password" value=""/></span>
<div id="globalError" class="col-sm-12 alert alert-danger" style="display:none"
th:text="#PasswordMatches.user">error
</div>
<div class="col-sm-12">
<br/><br/>
<button class="btn btn-primary" type="submit" onclick="savePass()"
th:text="#message.updatePassword">submit
</button>
</div>
</form>
</div>
</div>
<script th:inline="javascript">
var serverContext = [[@/]];
$(document).ready(function ()
$('form').submit(function(event)
savePass(event);
);
$(":password").keyup(function()
if($("#password").val() != $("#matchPassword").val())
$("#globalError").show().html(/*[[#PasswordMatches.user]]*/);
else
$("#globalError").html("").hide();
);
options =
common: minChar:6,
ui:
showVerdictsInsideProgressBar:true,
showErrors:true,
errorMessages:
wordLength: /*[[#error.wordLength]]*/,
;
$('#password').pwstrength(options);
);
function savePass(event)
event.preventDefault();
$(".alert").html("").hide();
$(".error-list").html("");
if($("#password").val() != $("#matchPassword").val())
$("#globalError").show().html(/*[[#PasswordMatches.user]]*/);
return;
var formData= $('form').serialize();
$.post(serverContext + "user/savePassword",formData ,function(data)
window.location.href = serverContext + "login?message="+data.message;
)
.fail(function(data)
if(data.responseJSON.error.indexOf("InternalError") > -1)
window.location.href = serverContext + "login?message=" + data.responseJSON.message;
else
var errors = $.parseJSON(data.responseJSON.message);
$.each( errors, function( index,item )
$("#globalError").show().html(item.defaultMessage);
);
errors = $.parseJSON(data.responseJSON.error);
$.each( errors, function( index,item )
$("#globalError").show().append(item.defaultMessage+"<br/>");
);
);
</script>
</div>
</body>
</html>
这将创建会话并完美更新密码。 但我想发送一个发布请求和一个 newPassword 以存储在数据库中。但无法创建会话。
Controller.java
@RequestMapping(value = "/user/savePassword", method = RequestMethod.POST)
@ResponseBody
public String savePassword(@RequestParam("newPassword") String newPassword)
final User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
userService.changeUserPassword(user, newPassword);
return "Password has been changed successfully. ";
这个
final User user = (User)
SecurityContextHolder.getContext().getAuthentication().getPrincipal();
当我直接从 UI App 中点击 URL 时,没有创建用户的会话。
请告诉我这样做的方法。
【问题讨论】:
【参考方案1】:很难理解发生了什么错误。如果我理解正确,并且你按照这个例子https://www.baeldung.com/spring-security-registration-i-forgot-my-password是无可挑剔的,那么在从信中检查令牌的时候,你应该已经被授权了。
我猜,应该是这里
public String validatePasswordResetToken(long id, String token)
PasswordResetToken passToken =
passwordTokenRepository.findByToken(token);
if ((passToken == null) || (passToken.getUser()
.getId() != id))
return "invalidToken";
Calendar cal = Calendar.getInstance();
if ((passToken.getExpiryDate()
.getTime() - cal.getTime()
.getTime()) <= 0)
return "expired";
User user = passToken.getUser();
Authentication auth = new UsernamePasswordAuthenticationToken(
user, null, Arrays.asList(
new SimpleGrantedAuthority("CHANGE_PASSWORD_PRIVILEGE")));
SecurityContextHolder.getContext().setAuthentication(auth); // authorization after validation of reset token
return null;
请提供更多关于您的情况的信息。给我一个完整的例子。或者你只是直接保存密码?
【讨论】:
先生,我正在使用“Flutter”应用程序作为前端。我只想重定向到用户可以输入new-password
的应用页面,但我无法在验证令牌后将信号定向到颤振应用。以上是关于使用 Spring 安全注册创建会话的主要内容,如果未能解决你的问题,请参考以下文章
会话创建和会话销毁事件中的 Spring 安全访问用户详细信息
Spring Boot 安全性:请求的 url 创建了不需要的 redis 会话