I've recently started reading about SAML and trying to implement something similar to the Spring's SAML-sample project to my existing Java Application(so please spare me if I ask something stupid!). My existing application has a Login.jsp which asks for user credentials and do the validation accordingly to login. I would like to implement the idea of SSO for my application.
So to start with, I've understood the Spring Saml-sample project quite well. In its SecurityContext.xml the samlIDPDiscovery bean is configured as:
<!-- IDP Discovery Service -->
<bean id="samlIDPDiscovery" class="org.springframework.security.saml.SAMLDiscovery">
<property name="idpSelectionPath" value="/WEB-INF/security/idpSelection.jsp"/>
</bean>
The idpSelection.jsp has the following html part code:
<h1>IDP selection</h1>
<%
WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(getServletConfig().getServletContext());
MetadataManager mm = context.getBean("metadata", MetadataManager.class);
Set<String> idps = mm.getIDPEntityNames();
pageContext.setAttribute("idp", idps);
%>
<p>
<form action="<c:url value="${requestScope.idpDiscoReturnURL}"/>" method="GET">
<table>
<tr>
<td><b>Select IDP: </b></td>
<td>
<c:forEach var="idpItem" items="${idp}">
<input type="radio" name="${requestScope.idpDiscoReturnParam}" id="idp_<c:out value="${idpItem}"/>" value="<c:out value="${idpItem}"/>"/>
<label for="idp_<c:out value="${idpItem}"/>"><c:out value="${idpItem}"/></label>
<br/>
</c:forEach>
</td>
</tr>
<tr>
<td> </td>
<td><input type="submit" value="Login"/></td>
</tr>
</table>
</form>
</p>
<p>
Metadata information
</p>
<%
response.sendRedirect("http://localhost:6443/spring-saml/saml/login/alias/defaultAlias? idp=http%3A%2F%2Fidp.ssocircle.com");
%>
So If I want to implement similar to above by doing appropriate changes to my Login.jsp and securityContext.xml for selecting appropriate IdP and redirecting to the selected Idp's Landing page on clicking login, how should I proceed? I've tried doing this since so long but I couldn't. Any help is highly appreciated.
As long as you're configuring your application based on the Spring SAML sample application you can simply redirect user to scheme://host:port/context/saml/login?idp=entityId where entityId can be found in your IDPs metadata. This will automatically start the SSO process and skip the discovery.
Related
I have a web application that will have two methods within a form to login.
Username and Password + a Login Button.
smart card login button.
Currently, we only have the Username and Password login. At some point, we will need to implement a smart card login. Most of our users already exist and will need to login with their username and password and then "register" their smart card to associate the username to the smart card via the database. I assume the smart card will utilize x509 certificates and I don't want to be prompted for the certificate as soon as the login page is visited. I would prefer that the certificates prompt appears after the smartcard login button has been clicked. I've seen this implemented at government sites like https://mypay.dfas.mil/#/. Anyway I can produce this approach using JSP, Spring Security and Java?
The following link is how I build the login application: https://howtodoinjava.com/spring-security/login-form-based-spring-3-security-example/
I've been told if I add the following to the security configuration I could use X.509 authentication with other options such as a form-based login.
<http>
...
<x509 subject-principal-regex="CN=(.*?)," user-service-ref="userService"/>
...
</http>
Unfortunately, I don't know how to tie this to the login-form.
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%# taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<%# taglib uri="http://www.springframework.org/tags" prefix="spring" %>
<html>
<body>
<h1 id="banner">Login to Security Demo</h1>
<form name="f" action="<c:url value='j_spring_security_check'/>"
method="POST">
<table>
<tr>
<td>Username:</td>
<td><input type='text' name='j_username' /></td>
</tr>
<tr>
<td>Password:</td>
<td><input type='password' name='j_password'></td>
</tr>
<tr>
<td colspan="2"> </td>
</tr>
<tr>
<td colspan='2'><input name="submit" type="submit"> <input name="reset" type="reset"></td>
</tr>
<tr>
<td colspan='2'><input name="Smart Card Login" type="submit"></td>
</tr>
</table>
</form>
</body>
</html>
I have this form and I want it to connect to an external database. I have no idea how to and after a lot of research its still not clear to me.
Here is my code. Any guidance will be helpful.
#{
ViewData["Title"] = "Index";
}
<h2>User Information</h2>
<p>This is your user information!</p>
<form action="Result">
First name:<br>
<input type="text" name="firstname" value=" ">
<br>
Last name:<br>
<input type="text" name="lastname" value=" ">
<br>
Role:<br>
<input type="text" name="Role" value=" ">
<br>
Ranking:<br>
<input type="text" name="Ranking" value=" ">
<br><br>
<input type="submit" value="Save">
</form>
I don't really know which direction to take this form. Many thanks in advance
You don't connect the actual form itself, you connect your backend to the DB, and you connect the form to your backend.
Make some sort of route to handle the form request and then connect to your database in that route, and use it to input the data to the database.
Related links:
https://docs.asp.net/en/latest/tutorials/first-mvc-app/working-with-sql.html
Your form should post data to an existing action inside an existing controller, and then, your database db connection already must be defined in your server-side MVC application.
At your point, probably, your form is looking for something called "Result"...
Now, I think that you are able to keep your research for solutions to your specific case.
I have declared Spring Security in my application.yml as a dependency and when running my app the default login form works as expected. I would like to style the form so my application is seamless.
In views/auth I have auth.gsp which contains the following code:
<form method="POST" action="${resource(file: 'j_spring_security_check')}">
<table>
<tr>
<td>Username:</td><td><g:textField name="j_username"/></td>
</tr>
<tr>
<td>Password:</td><td><input name="j_password" type="password"/></td>
</tr>
<tr>
<td colspan="2"><g:submitButton name="login" value="Login"/></td>
</tr>
</table>
</form>
This form appears as expected however when submitting the form nothing happens. I'm assuming it's because {resource(file: 'j_spring_security_check')} is not the action that it should be going to. I have got this code from here and I believe this is written with Grails 2 in mind. Any idea what the correct action is?
The following is the working customised login form:
<form method="POST" action="${resource(file: '/login/authenticate')}" class="form-signin">
<h2 class="form-signin-heading text-center">Login</h2>
<input type="text" class="form-control" name="username" placeholder="Username"/>
<input type="password" class="form-control" name="password" placeholder="Password"/>
<label class="checkbox text-center">
<input type="checkbox" value="remember-me" id="rememberMe" name="remember-me"> Remember me
</label>
<button class="btn btn-lg btn-default btn-block" type="submit">Login</button>
</form>
Key things to note are:
j_spring_security_check is now /login/authenticate
j_username is now username
j_password is now password
Documentation for Spring security 3 which is used for Grails 3 is here
I'm shocked to find that a blog post from six years ago isn't 100% correct. Perhaps you'll have better luck reading the documentation, in particular the "What’s New in Version 3.0" section.
I have put the ":spring-security-ui:1.0-RC1" into my BuildConfig and compiled it then I created the auth, register and securityInfo views and controller by using the spring ui command. I also put a user in my db to test it.
However, when I tested it I just get to the login page, after login in I get to the grails page back. However the button Register New User and Forgotten Passoword do not work, I only get redirected to the login page! Even though the file gets correctly rendered to *.html.
This is how the view structure looks like:
My ÙRLMappings look like that:
class UrlMappings {
static mappings = {
"/$controller/$action?/$id?(.${format})?"{
constraints {
// apply constraints here
}
}
"/"(view:"/index")
"500"(view:'/error')
}
}
I would appreciate your answer on my problem!
UPDATE
This is my auth.gsp:
<html>
<head>
<title><g:message code='spring.security.ui.login.title'/></title>
<meta name='layout' content='register'/>
</head>
<body>
<p/>
<div class="login s2ui_center ui-corner-all" style='text-align:center;'>
<div class="login-inner">
<form action='${postUrl}' method='POST' id="loginForm" name="loginForm" autocomplete='off'>
<div class="sign-in">
<h1><g:message code='spring.security.ui.login.signin'/></h1>
<table>
<tr>
<td><label for="username"><g:message code='spring.security.ui.login.username'/></label></td>
<td><input name="j_username" id="username" size="20" /></td>
</tr>
<tr>
<td><label for="password"><g:message code='spring.security.ui.login.password'/></label></td>
<td><input type="password" name="j_password" id="password" size="20" /></td>
</tr>
<tr>
<td colspan='2'>
<input type="checkbox" class="checkbox" name="${rememberMeParameter}" id="remember_me" checked="checked" />
<label for='remember_me'><g:message code='spring.security.ui.login.rememberme'/></label> |
<span class="forgot-link">
<g:link controller='register' action='forgotPassword'><g:message code='spring.security.ui.login.forgotPassword'/></g:link>
</span>
</td>
</tr>
<tr>
<td colspan='2'>
<s2ui:linkButton elementId='register' controller='register' messageCode='spring.security.ui.login.register'/>
<s2ui:submitButton elementId='loginButton' form='loginForm' messageCode='spring.security.ui.login.login'/>
</td>
</tr>
</table>
</div>
</form>
</div>
</div>
<script>
$(document).ready(function() {
$('#username').focus();
});
<s2ui:initCheckboxes/>
</script>
</body>
</html>
You probably need to add the following two rules in your grails.plugin.springsecurity.controllerAnnotations.staticRules. It is in the Config.groovy file.
'/register/index': ['permitAll'],
'/register/forgotPassword': ['permitAll'],
Otherwise, the spring security will bump your request back to the login/auth screen.
What about your controllers ?? I hear no mention of them you including them in your config file. Define your success handler and define a controller for successful login.
grails.plugin.springsecurity.successHandler.defaultTargetUrl = '/homePage'
Then if you already are being logged in then set access into the controllers using security annotations or using InterceptMapURL.
Looking at your problem you just haven't configured the security plugin well that's it. Well look at some other spring security implementation for grails in github, I think that will help you.
Simply add anonymous role to your RegisterController
import grails.plugin.springsecurity.annotation.Secured;
#Secured(['ROLE_ANONYMOUS'])
class RegisterController extends grails.plugin.springsecurity.ui.RegisterController {
}
I currently have a very simple model "Coupon". I suddenly am interested to add two more fields, "redeem_code" and "redeemed" to the model for obvious reasons.
I would like to make a view for a merchant to redeem a coupon based on a code.
The simplest approach that I can think of to just do this would be something like this:
def redeem
#renders the page
end
def redeem_post
redeem_code = params[:redeem_code]
deal = Deal.find_by_redeem_code(redeem_code)
if deal.nil?
# BUG: Somehow here you will be logged out
redirect_to deals_path
else
if deal.update_attribute(:redeemed, true)
redirect_to deals_path
end
end
end
As far as I am concerned, rails doesn't really support non restful interfaces. I tried digging up form helpers last night but I was not able to find anything so I just put togehter something real fast:
<form action="<%= deals_redeem_post_path %>" method="post">
<table>
<tr>
<th> Code: </th>
<td> <input type="text" name="redeem_code" /> </td>
</tr>
<tr>
<th></th>
<td> <input type="submit" text="Submit" /> </td>
</tr>
</table>
</form>
I am using devise. The bug that I am experiencing right now is when my user submits this form, he/she will be automatically logged out.
Any ideas how I can fix this or implement this more elegantly?
My guess is that you are missing the authenticity token (which prevents Cross Site Request Forgery (CSRF)) which is automatically generated. You want to use the form for helper for that generates this automatically.
<%= form_for(:coupon, :url => deals_redeem_post_path) do |f| %>
http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-form_for