Customizing WSO2 IS login error messages - authentication

I am using WSO2 5.2. I have created a custom UserStoreManager that extends JDBCUserStoreManager and is readonly. Here is a snippet from user-mgt.xml.
<UserStoreManager class="org.arbfile.wso2.user.ReadOnlyJDBCUserStoreManager">
<Property name="TenantManager">org.wso2.carbon.user.core.tenant.JDBCTenantManager</Property>
<Property name="ReadOnly">true</Property>
<Property name="ReadGroups">false</Property>
<Property name="WriteGroups">false</Property>
........
</UserStoreManager>
In terms of user authentication, I'm doing user/passw verification in the doAuthenticate() method of my custom class. I'm also doing other checks like IP filtering and user account locked. I can throw UserStoreException when these other items fail. The problem I'm having is setting the appropriate error message based on certain failure conditions. I found the following link https://docs.wso2.com/display/IS500/Customizing+Authentication+Error+Messages, however the information is too vague. I need to know how to set a "new" custom error message so the authentication endpoint can pass it to the login.jsp where it is rendered. Right now I get the exact same error message no matter what error occurs.
EDIT: Adding html form code for clarity:
<form action="../commonauth" method="post" id="loginForm">
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12 form-group">
<input id="username" name="username" type="text" class="form-control" tabindex="0" placeholder="Username">
</div>
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12 form-group">
<input id="password" name="password" type="password" class="form-control" placeholder="Password" autocomplete="off">
</div>
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12 form-group">
<input type="hidden" name="sessionDataKey" value='e04168f9-95c7-4b87-93af-60e1ecdc6273'/>
</div>
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12 form-group">
<div class="form-actions">
<button class="wr-btn green-ltgr col-xs-12 col-md-12 col-lg-12 uppercase font-extra-large" type="submit">Login</button>
</div>
</div>
</form>
I am using SAML and this is the form presented for form based login on the WSO2 server. The form action is "../commonauth". The form submission with username and password appears to be going against a different web app (and not the authenticationendpoint web app). The above code comes from basicauth.jsp.

Few months ago I had exactly same requirement but could not found proper solution. I found that BasicAutheticator every time sending the same error code to login page. As a workaround I changed my flow a little and decided to customize the login app instead of customizing WSO2 error code. I know it is a wrong practice but it solved my problem. Here is how my new architecture works.
I created a library with all logic of pre authentication checks, lets name it validation.jar
Then I added this library as maven dependency to login application which is authenticationendpoint.
Created a new servlet in login app, let's name it PreValidation.java
Modified the basicAuth.jsp and instead of submitting the form to /samlsso, Submitted the form to PreValidation servlet.
In PreValidation servlet, with the help of validation.jar do all validations except authentication ( which should be the task of WSO2).
If any Validation is failed, pass the corresponding error code back to to login.jsp and show the message on screen.
If all validations are done, submit the request to WSO2 and let the flow continue.
Hope this will help you.

Once the error codes are enabled from application-authentication.xml You can edit following JSPs to display error messages.
Login failed BasicAuth:- [IS_HOME]\repository\deployment\server\webapps\authenticationendpoint\basicauth.jsp
Remaining Attempts are over :- [IS_HOME]\repository\deployment\server\webapps\authenticationendpoint\retry.jsp
Please take a look at the URL in Get request. It contains the relevant error code. Hope this helps someone.

Related

ASP.Net Core Razor pages: how does <form class="needs-validation"> actually invoke client-side validation?

I'm working with a ASP.Net Core 3.1 web application.
If a Razor page has a form with class="needs-validation", then client-side validation is invoked for the fields in that form. Specifically, jquery-validation-unobtrusive gets called when the user clicks "Submit".
Q: How exactly does this occur? What "magic" links the HTML class "needs-validation" to the"validate()" Javascript code? Is there some CSS file somewhere that defines this linkage?
Q: Is "needs-validation" a Bootstrap class? Or is it standard HTML5/CSS3? Where/how is it defined?
These are some of the links I've found, but I still don't understand the linkage between class "needs-validation" invoking the validation code:
https://wakeupandcode.com/validation-in-asp-net-core-3-1/
https://getbootstrap.com/docs/4.0/components/forms/
https://github.com/aspnet/jquery-validation-unobtrusive
By default, asp.net core application use jQuery Unobtrusive Validation and https://jqueryvalidation.org/ plugin to achieve the client side validation. JQuery Unobtrusive Validation parses the data- attributes and passes the logic to jQuery Validation, effectively "copying" the server-side validation logic to the client. You can display validation errors on the client using tag helpers as shown here (without the class="needs-validation"):
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Movie.Title" class="control-label"></label>
<input asp-for="Movie.Title" class="form-control" />
<span asp-validation-for="Movie.Title" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Movie.Description" class="control-label"></label>
<input asp-for="Movie.Description" class="form-control" />
<span asp-validation-for="Movie.Description" class="text-danger"></span>
</div>
....
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
The class="needs-validation" is used for custom Bootstrap form validation messages (use HTML5 form validation), then, it will based on this class selector to find elements and validate the data. Check the Bootstrap Validation to learn how it works and how to use it.

How to stay on the same page after a form submission integrated to a Google form

In my website i have a contact form, and i've integrated it with a Google form. I've added the google form's execute URL as the action URL so once its submitted the form is being populated with the form data. the way i have done it
But when its being submitted, its redirecting to a google form's response page. What i need is once its submitted, to stay on the same page and give an alert. Im not sure how to do this in vue js. Any suggestion will be appreciated.
the content on the redirected page
{"result":"success","data":"{\"name\":[\"sdvsdv\"],\"company\":[\"dsvdv\"]}"}
Form in vue js view
<form method="POST" id="appointment-form" action="https://script.google.com/macros/s/AKfycbzRHvjfmIZdwKnOm26PeFv64OyyyGAfcr68MxvYw/exec">
<div class="form-group">
<input type="text" placeholder="Your name" name="name" class="form-control" id="name" required>
</div>
<div class="form-group">
<input type="text" placeholder="Company name" name="company" class="form-control" id="company" required>
</div>
<buttontype="submit" class="btn btn-default btn-block form-submit-btn">Submit</button>
</form>
After read your code properly, i found many errors.
How are you saving input values?
To save, you have to use ```v-model directive````
I guess you save the input values in somewhere. To avoid your problem, you can add a method and call it on submit, and inside the method save your input values.

Scaffolded Identity Razor Pages Forms don't submit unless there is a route parameter

This happens on all the Scaffolded Identity Razor Pages that do not include a route parameter in the Form definition, but let's take the ForgotPassword one as an example:
Here is the form as defined on the scaffolded page:
<form method="post">
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<label asp-for="Input.Email"></label>
<input asp-for="Input.Email" class="form-control" />
<span asp-validation-for="Input.Email" class="text-danger"></span>
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
When I click the submit button, nothing happens. The browser dev tools confirm nothing happens. The page does not submit to the server. (and yes, I have entered a valid email address; if I don't, then the jquery validation correctly displays the appropriate error messages.)
But I've found that if I change the form definition to include a route parameter, as follows:
<form asp-route-unusedArg="SomeValue" method="post">
then the submit button works fine, and the form is submitted to the server. (Even though the OnPostAsync method defined by the server code does not expect a parameter at all; it is defined as public async Task<IActionResult> OnPostAsync()). The way I figured this out was to compare the form definition with that of the Login form, which was working fine, and had a route parameter for returnUrl.
What is going on here? Why is the form not submitting unless I add a route parameter?

i want to change url parameters

hi my url is something like this abc.domain.com/add/firstname/phone/email which is api link. i want to change parameters first name,phone,email when user enters in form. please let me know if anyone can help. thanks in advance.
add/?Client+Name=&Phone+number=&Email+ID=&Partner+ID=AUOVML i dont want url in this format. format must be as i mentioned in first line. i have done something like this:
<form method="get" action="http://abc.domain.com/add/">
<div class="d-nt-signup">
<div class="d-nt-field-wrap">
<input type="text" label="Name*" id="first_name" name="Client Name" active-color='#FB165B' class="d-nt-login-filed">
</div>
<div class="d-nt-field-wrap">
<input type="text" label="Mobile*" id="mobile" name="Phone number" active-color='#FB165B' class="d-nt-login-filed">
</div>
<div class="d-nt-field-wrap">
<input type="email" label="Email*" id="email ID" name="Email ID" active-color='#FB165B' class="d-nt-login-filed">
</div>
<div class="d-nt-field-wrap">
<input type="hidden" name="Partner ID" value="AUOVML">
</div>
When you do a get request with a form you will get the names and values of the form inputs added to the URL like that.
You can get around that by using a post request instead. Change method="get" to be method="post".
Developers will often handle the result of the form being sent with PHP. Change the action to point to a PHP file, and then in the PHP file you can access the form data through the $_post array like so $_POST["form_input_name"].
See http://php.net/manual/en/tutorial.forms.php for an example of echoing back data typed into a form.

Grails acegi plugin remember me not working

Im am having problems with the remember me functionality of the grails acegi plugin (version 0.5.3)
The first time I login I check the remember me check box and login. This works. I then shutdown my browser and restart it and browse to the app. The login page is presented with the user name populated, password empty and remember me check box checked. I would have expect to navigate straight into the application (http://localhost:8080/application normally redirects to my landing page). If I try and manually login (enter password) it now doesnt work, I cant get past the login page.
Here is my login form:
<form action='${postUrl}' method='POST' id='loginForm' class='cssform'>
<p>
<label for='j_username'>Email</label>
<input type='text' class='text_' name='j_username' id='j_username' value='${request.remoteUser}' />
</p>
<p>
<label for='j_password'>Password</label>
<input type='password' class='text_' name='j_password' id='j_password' />
</p>
<p>
<label for='remember_me'>Remember me</label>
<input type='checkbox' class='chk' name='_spring_security_remember_me' id='remember_me'
<g:if test='${hasCookie}'>checked='checked'</g:if> />
</p>
<p>
<input type='submit' value='Login' />
</p>
</form>
SecurityConfig.groovy
/** rememberMeServices */
cookieName = 'grails_remember_me'
alwaysRemember = false
tokenValiditySeconds = 1209600 //14 days
parameter = '_spring_security_remember_me'
rememberMeKey = 'grailsRocks'
This is just the default generated behavior. Am I missing something simple? Do I need to manually setup rememberMeServices or something?
I have confirmed that the "grails_remember_me" cookie is being created by using the chrome developer tools. I also get this same behavior with firefox.
Any ideas? Thanks
Never really got to the bottom of this. The way I "fixed" it was by upgrading to the new spring security plugin.
http://grails.org/plugin/spring-security-core