session create using spring security registration

Viewed 229

I am working with the registration processing using the spring security following the article of building https://github.com/Baeldung/spring-security-registration. As per this article, the HTML pages take the input and insert it into the database.

I am working with a Flutter application on the front-end. I want that when the user requests to reset password a link is sent to the email of a user and when the user clicks on the verification link it will create a session and redirect to the UI Page on the app to write the New Password. When the user enters the New Password it will update the password of that user.

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>

This will create the session and update the password perfectly. But I want to send a post request and a newPassword to store in the database. But unable to create the session.

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. ";
    }

This

final User user = (User) 
SecurityContextHolder.getContext().getAuthentication().getPrincipal();

is not creating the session of the user when I directly hit the URL from UI App.

Please tell me the way to do so.

1 Answers

it's hard to understand what happened wrong. If I understood correctly, and you follow this example https://www.baeldung.com/spring-security-registration-i-forgot-my-password is impeccable, then at the time of checking the token from the letter, you should have been authorized.

I guess, it should be here

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;
}

Please, give some more about your situation. Give me a full example of this. Or you just what to save a password directly?

Related