State after login with JSF - jsf

I am new to JSF and want to create the login part of an app. I have a login page
where I validate logins against a database. That is fine, but I can not figure out the logic
in the following part. A legal user should be redirected to her own profile page and non legal users to a common error page. How do I "transport" the identity from the login to the profile page. All the info I need for a profile page i can get from the database so I kind of want to transport a bean from the login to create a user dependent view. I have looked at tutorials online but could not find examples except for the even simpler example where there is no use of user identity and eg.password and username is simply matched against hard coded values. I think there is some underlying "idea" I don't get because this should ne simple, right ?

Put it in a session scoped managed bean. Here's a basic kickoff example:
#ManagedBean
#SessionScoped
public class ActiveUser {
private User user = new User();
#EJB
private UserService userService;
public String login() {
User found = userService.find(user);
if (found == null) {
setGlobalMessage("Invalid login, try again");
return null;
} else {
user = found;
return "userprofile";
}
}
public void isLoggedIn() {
return user.getId() != null;
}
// ...
}
You can intercept on its presence in a filter.
See also
Prevent accessing restricted page without login in Jsf2
Is there any easy way to preprocess and redirect GET requests?

Related

shiro web step by step example not work,stormpath is moved

Shiro web example
I follow this, but in step 2, the stormpath is moved to another site okta, so I don't know what shall I do.
There is an exception:
java.lang.IllegalStateException: Unable to load credentials from any provider in the chain.
So I wrote a reamls by myself.
public class CustomSecurityRealm extends JdbcRealm{
#Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
char[] psw = upToken.getPassword();
String username = upToken.getUsername();
return new SimpleAuthenticationInfo(username, psw, getName());
}
#Override
public void setDataSource(DataSource dataSource) {
// TODO Auto-generated method stub
DruidDataSource ds=new DruidDataSource();
ds.setUrl("jdbc:mysql://localhost:3306/test2?useUnicode=true&characterEncoding=utf8&autoReconnect=true&rewriteBatchedStatements=TRUE");
ds.setUsername("root");
ds.setPassword("root");
dataSource=ds;
}
}
And in shiro.ini I change securityManager.realm = $stormpathRealm to securityManager.realm = realm.CustomSecurityRealm
But exception is the same. Or sometimes no error when I delete it from tomcat and add again, but home page is not found --404.
I hate this, I just want to see how to use shiro in web project,why it is so hard?
I have no jndi, so I didn't copy from this example, I just want to make things simple. How can I run the web sample?
Take a look at the examples in https://github.com/apache/shiro/tree/master/samples
We will get that tutorial updated too.

ASP.Net MVC5: How to redirect and show right error message when user does not have a specific role for action

after login user can go to any action but think when action is decorated with authorized attribute and role names are specific there. just refer a sample code.
public class HomeController : Controller
{
[Authorize(Roles = "Admin, HrAdmin")]
public ActionResult PayRoll()
{
return View();
}
}
suppose user Foo has no role like Admin or HRAdmin then what will happen when user foo will try to access PayRoll action ?
in this kind of situation i want to redirect user to my error page where i will show a friendly message to user. please guide me how to do it ?
do i need to write a custom authorized attribute from there i need to check user has those roles are not and then redirect user from there?
I don't know if that's the best way to do it, but here's how I did it:
using System.Web.Mvc;
namespace YourNamespace
{
public class AccessDeniedAuthorizeAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
// Redirect to the login page if necessary
if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
filterContext.Result = new RedirectResult(System.Web.Security.FormsAuthentication.LoginUrl + "?returnUrl=" + filterContext.HttpContext.Request.Url);
return;
}
// Redirect to your "access denied" view here
if (filterContext.Result is HttpUnauthorizedResult)
{
filterContext.Result = new RedirectResult("~/Account/Denied");
}
}
}
}
Controller:
public class HomeController : Controller
{
[AccessDeniedAuthorize(Roles = "Admin, HrAdmin")]
public ActionResult PayRoll()
{
return View();
}
}
That's all you have to do if your User has its Roles defined correctly. If you are not using ASP.NET Identity to manage your users and roles, you will need some more code to make this work, in that case this might help you: How can I attach a custom membership provider in my ASP.NET MVC application?.

Liferay - autologin hook/portlet doesn't logout the current user

It seems Liferay's autologin hook doesn't logout the current user. So I tried to do it programmatically with the following method call:
request.getSession().invalidate();
but with no success.Does anyone had the same issues with the auto-login hook ?
Hi to logout you have to invalidate the cookies and then invalidate the session see the Liferay LogoutAction for more detail
https://github.com/liferay/liferay-portal/blob/6.2.x/portal-impl/src/com/liferay/portal/action/LogoutAction.java
The main problem is that if a user is logged in, an autologin filter is not executed, so you can't do any logout action in it.
For my solution I created a servlet filter which check some paramteres for autologin and execute logout process. For creating a filter I follow this guide: http://www.liferaysavvy.com/2016/02/liferay-servlet-filter-hooks.html
My code for logout in doFilter method (in servlet filter):
final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
final HttpSession session = request.getSession(false);
if (session != null)
{
session.invalidate();
}
filterChain.doFilter(request, response);
In Liferay 7.2, create a module portlet and do the following:
At the top after import add:
#Component(immediate = true, property = {"key=login.events.pre"}, service = LifecycleAction.class)
Customize your class as below:
public class LoginPreAction implements LifecycleAction
Add:
lifecycleEvent.getRequest().getSession().invalidate();
this will invalidate your session
Now send redirect:
try {
lifecycleEvent.getResponse().sendRedirect("/c/portal/logout");
} catch (IOException e) {
System.out.println("IOException while redirecting:::: "+e.getStackTrace());
}

JSF navigating to a different view programatically

My application has a save and retrieve function. I have the save/retrieve working in that the objects are saved to a database and retrieved correctly. However, in my retrieve landing page, depending on the state of the saved application, I either want to validate some details with the user, or silently navigate to the last accessed view. The latter is where I'm having trouble.
We're using spring beans and in my SaveAndRetrieve page bean I have:
#PostConstruct
public void initialise() {
caseNotFound = false;
caseReference = saveAndRetrieveActionHandler.getRequestedCaseReference();
LOGGER.debug("Retrieve initialise. Case ref is {}", caseReference);
if (caseReference != null) {
try {
saveAndRetrieveActionHandler.retrieveApplicationByCaseRef();
LOGGER.debug("Retrieve initialise - case found");
final NavigationOutcome outcome = saveAndRetrieveActionHandler.getLastAccessedView();
if (outcome.getApplicationState() == ApplicationState.QUOTE) {
LOGGER.info("Quote retrieved, navigating to view");
// HERE IS WHERE THE TROUBLE LIES! THIS DOESNT WORK
FacesUtils.setNextViewNavigation(outcome.getViewId());
}
} catch (final FrameworkException fe) {
LOGGER.debug("Exception caught {}", fe);
caseNotFound = true;
}
}
}
outcome is an enumeration containing amongst other things the view I need to navigate to, and the application state (another enumeration). If applicationState is quote, I want to silently navigate. For all other applicationStates I want to challenge the user to verify them.
My facesUtils method is:
public static void setNextViewNavigation(final String p_lastAccessedViewId) {
if (p_lastAccessedViewId != null) {
getCurrentViewRoot().setViewId(p_lastAccessedViewId);
}
}
I've also tried calling this method
public static void navigateToOutcome(final String p_outcome) {
final FacesContext context = getFacesContext();
final NavigationHandler navigationHandler = context.getApplication().getNavigationHandler();
navigationHandler.handleNavigation(context, null, p_outcome);
}
Despite my efforts, I'm seeing the landing page wheras I want to silently navigate to the saved page
Basically I want to abort the current lifecycle and reset the viewroot to the saved view. (note I am not saving the component tree itself, just my business objects)
One more piece of information, this is jsf1.2, but with facelets. I cannot use any jsf2 specific functionality, nor can I use any third party JSF extenstions.
Help please!
We solved this by using a ui:include tag with the src attribute being a jsf method that determines the name of the page to navigate to.

Programmatically control login with Servlet 3.0

I've tested the default security containers in Glassfish 3.0.1 and come to the conclusion that I won't spend any more time on that. Instead I want to control the verification myself. But I need some guidance to get me on right track.
At the moment I have a UserBean that has a login/logout function (see below). And I don't want to use the *j_security_check* built in container, but use core JSF 2.0.
My questions are;
Do I need a ServletFilter to redirect traffic if the user is not logged in (if accessing certain folders)?
How do I store User Pricipals after the user successfully logged in ?
Appreciate any help or link to a example, greetings Chris.
PS. Excuse me for clustering two questions together
#ManagedBean
#SessionScoped
public class UserBean {
private AuthenticateUser authenticateUser;
...
public String login() {
FacesContext context = FacesContext.getCurrentInstance();
HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
JsfUtil.log("Username : " +authenticateUser.getUserName());
JsfUtil.log("Password : " +authenticateUser.getPassword());
AuthenticateUser authRequest = authenticationFacade.find(authenticateUser);
try {
if(!authRequest.equals(authenticateUser))
return "/loginError";
request.login(authenticateUser.getUserName(), authenticateUser.getPassword());
return "";
} catch(ServletException e){
JsfUtil.addErrorMessage(e, "Incorrect username or password, please try again.");
return "/loginError";
}
...
public String logOut() {
String result = "/index?faces-redirect=true";
FacesContext context = FacesContext.getCurrentInstance();
HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
try {
request.logout();
} catch (ServletException e) {
JsfUtil.log("Failed to logout user!" +e.getRootCause().toString());
result = "/loginError?faces-redirect=true";
}
return result;
}
When you want to utilize request.login(), then you should really have configured a Realm in the container which represents the user database. But you seem to have replaced the Realm by some AuthenticationFacade. In this case, the request.login() is not useful for you.
You need to just put the user in the session scope and intercept on that. Here's a kickoff example:
#ManagedBean
#SessionScoped
public class UserManager {
#EJB
private UserService userService;
private String username;
private String password;
private User current;
public String login() {
current = userService.find(username, password);
if (current == null) {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Unknown login, try again"));
return null;
} else {
return "userhome?faces-redirect=true";
}
}
public String logout() {
FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
return "index?faces-redirect=true";
}
public boolean isLoggedIn() {
return current != null;
}
// Getters/setters (but do NOT provide a setter for current!)
}
When taking authentication in hands like this, then you definitely need a filter to restrict access. When using container managed security you would typically specify it as <url-pattern> of <security-constraint> for this. But without it, you've to take it in your hands. It's good to know that JSF managed beans are keyed by their managed bean name in any scope.
UserManager userManager = ((HttpServletRequest) request).getSession().getAttribute("userManager");
if (userManager == null || !userManager.isLoggedIn()) {
((HttpServletResponse) response).sendRedirect("login.xhtml");
} else {
chain.doFilter(request, response);
}
Map the above filter on the desired URL-pattern.
When you still want to reconsider using container managed authentication, then the following related answers may be useful:
Java EE Login Page Problem (and Configuring Realm in Glassfish)
Performing user authentication in Java EE / JSF using j_security_check
Be aware if you are if you are using JDBC realm security. There are some fixed/expected words in the fields where you configure the realm in the Glassfish admin console.
In the JAAS Context: filed, you have to type: jdbcRealm. This keyword makes the security container use the expected JDBC realm. If you type something else, it won't work.
Here is good example, done by Gordan Jugo; Netbeans/Glassfish JDBC Security Realm

Resources