Get name of username with SpringSecurity and JSP - spring-security

I wonder how to get the username by springsecurity, for example, my user table looks like this:
username - password - name
Authentication is done by the username + password, if I use these two options:
<%= request.getUserPrincipal().getName() %>
<%= SecurityContextHolder.getContext().getAuthentication().getName() %>
He will show me the username value, but in case my username is a value personal document, so I would only show the value of the field name.
Is how to do this? I'm using JSP + JSTL. Thank you.

You can use the spring security JSTL tags :
<%# taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
and put in your JSP code the following code :
<sec:authentication property="principal.username" />
you will have acess to all Principal properties .

Related

Render password value using f:field in Grails

I’m using f:field in order to render a custom Cmd object.
class CustomCmd implements Validateable {
String user
String password
static constraints = {
user blank: false, email: true
password blank: false, password:true
}
}
Then in my gsp page I use
<fieldset class="form">
<f:with bean="${cmd}">
<f:field property="user"/>
<f:field property="password"/>
</f:with>
</fieldset>
The password is not shown on the page (with the standard **** bullets): the field has no value, but the user field is filled with the right value.
There is a way to fill the password field using f:field tag?
This seems to be the wanted behaviour:
https://github.com/grails-fields-plugin/grails-fields/issues/60
I'm not agree with the developers... BTW this is not a bug

Grails update/rerender layout at runtime

The situation is that I have a layout application.gsp that defines the layout for all the pages except the login page. Inside the layout is a header that should display the name of the current logged in user (Spring Security plugin). The problem is that if the user just registers or uses oAuth for the first time (same as registering) then when he logs in he will see and empty spot instead of a username because the layout was rendered before the username was available. If he logs out/logs in again he will of course see his username.
P.S. Moving the header outside of the layout is not an option, because it will cause massive code duplication.
Is there a way around this?
I will answer my own question for future generations trying to solve the same problem.
The trick is in using a decorator design pattern and the badly documented g:pageProperty gsp tag.
views/layouts/application.gsp:
....
<li class="dropdown menu">
<a href="#" class="dropdown-toggle"
data-toggle="dropdown"><g:pageProperty name="page.username"/></a>
<ul class="dropdown-menu">
<li>Preferences</li>
<li>
<a href="${resource(file: 'j_spring_security_logout')}"
class="navbar-btn btn-danger btn">Logout</a></li>
</ul>
</li>
....
views/index.gsp:
....
<body>
<content tag="username">
<g:username username="${username}"/>
</content>
....
taglib/UsernameTagLib.groovy:
class UsernameTagLib {
def springSecurityService
/**
* Check if the username is already available, else inject newly created username into the layout
*
* #attr username REQUIRED that was received from the newly registered user
*/
def username = { attrs ->
String currentUsername = springSecurityService.getCurrentUser()?.username
if (currentUsername) {
out << currentUsername
} else {
out << attrs.username
}
}
}
The newly created username is passed to views/index.gsp when the user is finished through the whole oAuth process.
controllers/OauthCallBackController.groovy
....
def facebook() {
Token facebookAccessToken = (Token) session[oauthService.findSessionKeyForAccessToken('facebook')]
if (facebookAccessToken) {
String username = oauthCallBackService.facebook(facebookAccessToken)
render view: '/index', model: [username: username]
} else failure()
}
....
Basically the username travels upwards until it reaches the layout, which allows me to use the username in the layout header and propogate it on all the pages that need the layout.
You can check it with SecurityTagLib helper of Spring Security Core.
In your application.gsp you can have:
...
<sec:ifLoggedIn>
<!-- Display user field with sec:loggedInUserInfo tag -->
Welcome Back <sec:loggedInUserInfo field="fullName"/>
<!-- Check if user have all specified privileges -->
<sec:ifAllGranted roles="ROLE_ADMIN,ROLE_SUPERVISOR">
You've ROLE_ADMIN AND ROLE_SUPERVISOR privileges.
</sec:ifAllGranted>
<!-- Check if user have at least one specified privileges -->
<sec:ifAnyGranted roles="ROLE_ADMIN,ROLE_SUPERVISOR">
You've ROLE_ADMIN OR ROLE_SUPERVISOR privileges.
</sec:ifAnyGranted>
</sec:ifLoggedIn>
<sec:ifNotLoggedIn>
It's public content, anonymous user.
</sec:ifNotLoggedIn>
...
You can also use: <sec:ifNotGranted roles="ROLE_USER"></sec:ifNotGranted>
If you are using Spring Security Core plugin, you can reauthenticate user in your controller.
springSecurityService.reauthenticate user.username

A required anti-forgery token was not supplied or was invalid when deployed on IIS

I have an MVC application.
I have [ValidateAntiForgeryToken] on each Post action.
When i run it on my local computer, it is working well. The problem is when i deploy it to my development server. I am encountering the Required anti-forgery token error.
Is there something that i must configure in IIS in order for my application to work?
Thanks in advance!
You also need to include the Antiforgery token in the forms you want to protect, i.e.
<%= Html.AntiForgeryToken() %>
You must include the above in your forms that post through to the controller actions that are decorated with the [ValidateAntiForgeryToken] attribute as illustrated below:
<% using(Html.Form("{ControllerHere}", "{ActionHere}")) { %>
<%= Html.AntiForgeryToken() %>
<!-- rest of form goes here -->
<% } %>

Hide email or website addresses unless authenticated

I'm developing a job board website with ASP.Net MVC and want to block any email or website addresses from being visible to unregistered users.
So for example if an employer posts a job and includes something in the description like 'To apply send an email to myemail#email.com', I want it to display 'To apply send an email to hidden link - please login or register' or words to that effect. When they login the links then become available.
I'm still very much at the learner stage with ASP.Net MVC so I'm not really sure where to start with this. I'm not sure if this is the right thing to do or if there is an alternative approach.
Many thanks for any help.
only777,
you may be best served by creating an DisplayTemplate for email addresses and running your code thro those. here's an example of what i mean. Inside your view:
<%: Html.DisplayFor( m => m.Email, "ViewIfAuthenticatedTemplate" ) %>
and then under views/shared/DisplayTemplates, add an item called ViewIfAuthenticatedTemplate.ascx and add the following code to it:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<string>" %>
<% if(Request.IsAuthenticated) { %>
<%: Model %>
<% } else {%>
<%: Html.ActionLink("hidden link - please login or register", "MyAction", "MyController") %>
<% } %>
not sure if the syntax is 100% correct, but you get the gist..
[edit] - in fact, you could use this DisplayTemplate for ANY text that had to be hidden if not authenticated.
Use a regex search to look for email addresses in the posting and replace that with the link you want for the unregistered users.
[Updated]
public ActionResult ShowPosting()
{
var description = descriptionFromDB();
if(!registeredUser)
{
model.Description = logicToReplaceTheEmailAddress(description);
}
else
{
model.Description= description;
}
return View(model);
}

How to attemp sec:loggedInUserInfo into a variable in gsp

I want to get value of sec:loggedInUserInfo and attempt into a variable named user.
My code looks like this:
<sec:loggedInUserInfo field="username" />
<%
def user = *value of field loggedInUserInfo *
%>
Is it possible for doing that?
This is simpler and works fine for me:
<g:set var="user" value="${sec.username()}" />
To assign any field of the UserDetails instance referred to by <sec:loggedInUserInfo> to a variable you can use:
<g:set var="fullName" value="${sec.loggedInUserInfo(field:'fullName')}" />
(see also Custom User Details)
If you want the user object in the gsp, just pass it back as part of the model map from the controller. in a controller action do
def user = springSecurityService.getCurrentUser()
render view: 'yourgsp', model: [user: user]
I am not sure if we can use that tag directly, I couldn't find it earlier, so I have made my custom tag for this purpose
<m:userName id="${session.SPRING_SECURITY_CONTEXT?.authentication?.principal?.id}"/>
def userName = { attrs ->
Long id = attrs['id'] ? attrs['id'].toLong() : null
User user = User?.get(id);
out << user?.firstName
}
I have created one taglib as loggedinUser which is added on gsp page as :
Welcome <g:loggedInUser/> !
Which is showing logged In username on top of each gsp in my project. In custom tag library my code is as follows :
def springSecurityService
def loggedInUser={
if(springSecurityService.getPrincipal().equals("anonymousUser")){
response.sendRedirect("${request.contextPath}/login/auth")
}else{
out <<"${springSecurityService.currentUser.username}"
out << """ [${link(controller:"logout"){"Logout"}}]"""
}
}
So it's showing on each page as : Welcome USERNAME[Logout] !

Resources