Redirect to page in liferay Login - hook

I am creating a Hook to check-user on login, and depending on some parameters it will be redirected to one custom page or another.
I am doing this:
Portal.properties
#Gestion evento login
login.events.post=com.liferay.portal.events.AccionLogin
auth.forward.by.last.path=true
Action Class
public class AccionLogin extends Action {
#Override
public void run(HttpServletRequest request, HttpServletResponse response) throws ActionException {
try {
doRun(request, response);
} catch (Exception e) {
throw new ActionException(e);
}
}
protected void doRun(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpSession sesion = request.getSession();
User usuarioLogin = PortalUtil.getUser(request);
// Recupero la lista de roles
ArrayList<Role> roles = UtilRoles.getIntExtRol();
// Compruebo si el usuario pertenece al grupo
if (UtilLdap.esGrupo(request, usuarioLogin.getScreenName())) {
Constantes._log.info("El usuario es Interno en el Ldap vector. Gestiono su rol");
UtilRoles.setRoleIfNotHave(usuarioLogin, roles, Constantes.INTERNOS);
sesion.setAttribute(WebKeys.LAST_PATH, UtilUrls.generaLasthPath(request, Constantes.INTERNOS));
} else {
Constantes._log.info("El usuario es externo en el Ldap vector. Gestiono su rol");
UtilRoles.setRoleIfNotHave(usuarioLogin, roles, Constantes.EXTERNOS);
sesion.setAttribute(WebKeys.LAST_PATH, UtilUrls.generaLasthPath(request, Constantes.EXTERNOS));
}
}
}
This method:
sesion.setAttribute(WebKeys.LAST_PATH, UtilUrls.generaLasthPath(request, Constantes.EXTERNOS));
do it:
return new LastPath(StringPool.BLANK,Constantes.GROUPINTRANET+Constantes.SEPARADOR+Constantes.INICIOINTERNOS,
new HashMap<String, String[]>());
Generates group/intranet/pageforexterns, and same for interns but when I login I have a cookies error and a redirect error.
What am I doing wrong?
Thanks

Instead creating new instance of LastPath, you just get LastPath object by LastPath lastPath=(LastPath)session.getAttribute(WebKeys.LAST_PATH); and use lastPath.setPath(PATH) to avoid any errors.

Related

Intercept user visits a group

I am new to liferay and I need to enhance my User Object with a Map(groupId, lastVisitedDate) after a user visited a group.
Any ideas when, where and how I can intercept this request and enhance my user with the called groupId and the current Date?
I solved my issue by creating a hook which extends the portal.properties.
In this properties file I created this property
servlet.service.events.pre=org.my.company.project.event.MyCustomAction
the MyCustomAction Class extends Action.
This is how I got the necessary informations
#Override
public void run(HttpServletRequest request, HttpServletResponse response)
throws ActionException {
try {
User user = PortalUtil.getUser(request);
ThemeDisplay themeDisplay = (ThemeDisplay) request
.getAttribute(WebKeys.THEME_DISPLAY);
Group group = themeDisplay.getLayout().getGroup();
[...]
} catch (Exception e) {
throw new ActionException(e);
}
}

How to restrict access if user is not logged in

My project has a template main.xhtml and three views login.xhtml, dashboard.xhtml, new.xhtml. Once I login in login.xhtml, the LoginBean will validate and if successful, then it will take to dashboard.xhtml. If user need to create an new record he click the new button which takes to new.xhtml.
But the problem is, if dashboard.xhtml is requested directly from browser, then it is working without login. Do I need to check every view that the user is logged in? How can I achieve this?
It sounds like as if you're homegrowing authentication. In that case, you need to also homegrow access restriction. That is normally to be done using a servlet filter.
Assuming that you're logging in as follows in a #RequestScoped bean,
public String login() {
User user = userService.find(username, password);
FacesContext context = FacesContext.getCurrentInstance();
if (user != null) {
context.getExternalContext().getSessionMap().put("user", user);
return "dashboard.xhtml?faces-redirect=true";
} else {
context.addMessage(null, new FacesMessage("Unknown login, try again."));
return null;
}
}
Then you can check for the logged-in user in a #WebFilter("/*") filter as follows:
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
HttpSession session = request.getSession(false);
User user = (session != null) ? session.getAttribute("user") : null;
String loginURL = request.getContextPath() + "/login.xhtml";
boolean loginRequest = request.getRequestURI().startsWith(loginURL);
boolean resourceRequest = request.getRequestURI().startsWith(request.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER);
if (user != null || loginRequest || resourceRequest)) {
chain.doFilter(request, response);
} else {
response.sendRedirect(loginURL);
}
}
Note thus that this would continue the request when the user is logged in, or when the login page itself is requested directly, or when a JSF resource (CSS/JS/image) is been requested.
If you were using container managed authentication, then the filter would have been unnecessary. See also How to handle authentication/authorization with users in a database?

Liferay 5.2.3 portlet configuration page issue

I wrote a portlet that has custom conf page here is configuration-action-class:
public class ConfigurationActionImpl implements ConfigurationAction {
private static Logger log = Logger.getLogger(ConfigurationActionImpl.class);
private config conf=config.getInstance();
public String render(PortletConfig config, RenderRequest renderRequest, RenderResponse renderResponse) throws Exception {
if(renderRequest.isUserInRole("administrator")){
log.info("UserRole:::admin");
return "/config.jsp";
}else if(renderRequest.isUserInRole("guest")){
log.info("UserRole:::guest");
}else if(renderRequest.isUserInRole("power-user")){
log.info("UserRole:::power-user");
return "/config.jsp";
}else if(renderRequest.isUserInRole("user")){
log.info("UserRole:::user");
}else{
log.info("UserRole:::dafug");
}
return "/config.jsp?mode=guest";
}
public void processAction(PortletConfig config, ActionRequest actionRequest, ActionResponse actionResponse) throws Exception {
conf.Names.clear();
String count = ParamUtil.getString(actionRequest, "count");
String portletResource = ParamUtil.getString(actionRequest, "portletResource");
PortletPreferences prefs = PortletPreferencesFactoryUtil.getPortletSetup(actionRequest, portletResource);
String[] list=count.split("/");
for(String a : list){
if( a!=null&& !a.equals("")){
String en = ParamUtil.getString(actionRequest,"En"+a);
String pa = ParamUtil.getString(actionRequest,"Pa"+a);
if(!en.equals("")&&!pa.equals("")){
conf.Names.put(pa,en);
log.info("word::"+en+"::::"+pa);
prefs.setValue("En"+a,en);
prefs.setValue("Pa"+a,pa);
}else if(a!=null&& !a.equals("")){
count=count.substring(0,count.lastIndexOf("/"+a))+count.substring(count.lastIndexOf("/"+a)+("/"+a).length());
}
}
}
prefs.setValue("count",count);
prefs.store();
}
public void serveResource(ResourceRequest request, ResourceResponse response){
log.info("HERE in conf");
}
}
This class worked fine for only one time after clicking on return to full page, the button that locate in right corner of portlets does not work and I cannot go to configuration page again!
and also the menu bar in up right corner of portal did not work after getting back from configuration page unless I delete my portlet and all of them will work fine again!
I solved this problem.
My problem is that first I should change all the to
and I change all of my JQuery code to JavaScript because some how these version of JQuery that I used generates some error with this version of Liferay (5.2.3)

How to use HttpServletRequest#login() programmatic login with SHA-256 configured security realm

i have read there, i am using glassfish 3.1.1 security realm configured with sha-256 digest algorithm. is there any tutorial about this ? maybe i am blethering, i am trying to login with this code:
public void login() throws NoSuchAlgorithmException {
FacesContext context = FacesContext.getCurrentInstance();
HttpServletRequest request = (HttpServletRequest)context.getExternalContext().getRequest();
EntityManager em = emf.createEntityManager();
boolean committed = false;
try {
FacesMessage msg = null;
EntityTransaction entr = em.getTransaction();
entr.begin();
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(password.getBytes());
byte byteData[] = md.digest();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < byteData.length; i++) {
sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
}
password = sb.toString();
Query query = em.createQuery("SELECT COUNT(u) FROM EntityUser u WHERE u.userName = :userName AND u.password = :password")
.setParameter("userName", userName).setParameter("password", password);
long result = (long)query.getSingleResult();
if (result == 1) {
request.login(userName, password);
msg = new FacesMessage();
msg.setSeverity(FacesMessage.SEVERITY_INFO);
msg.setSummary("You are logged in");
}
entr.commit();
committed = true;
} catch (ServletException e) {
context.addMessage(null, new FacesMessage("wrong username or password"));
}
finally {
if (!committed) entr.rollback();
}
} finally {
em.close();
}
}
result variable returns 1, but request.login(userName, password); method in if condition always throws servletexception.
Can you post the exception stacktrace? That way it would be easier to understand the source of the exception. But judging from your currently supplied code, you should supply in
request.login(userName, password);
the password as the plain-text password and not the hashed password.
Interface HttpServletRequest
ServletException - if the configured login mechanism does not support username password
authentication, or if a non-null caller identity had already been established (prior to
the call to login), or if validation of the provided username and password fails.
There can be a lot of reasons that login fails. You've just checked if appropriate user and password are in table. Glassfish makes two queries - in authenticate process - to two tables. One to table specified as userTable, and second to groupTable which are determined in security realm definition. Check if web.xml and glassfish-web.xml are correct too.
the questioned problem is whole about method
request.login(userName, password);
Author made everything right, even his own authentication way of working with users database, but request.login needs for authentication realm be set up, to be used by this method. And you have your own, you dont need separate request.login authentication. For the case you need it - thats how you do it jdbc-realm-setup-with-glassfish-v3
So, after you get the result=1, you set up your context.getExternalContext().getSessionMap().put("user", u);
and send redirection context.getExternalContext().redirect(context.getExternalContext().getRequestContextPath() + "какой-то модуль.xhtml");
and use webfilter to block access to /Pages/*.xhtml without logging in.
#WebFilter("/Pages/*")
public class LoggingFilter implements Filter {
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse res = (HttpServletResponse)response;
User user = (User) req.getSession().getAttribute("user");
if(user != null){
chain.doFilter(request,response);
}
else res.sendRedirect(req.getContextPath()+"/запрос_учетных_данных.xhtml");
}
#Override
public void init(FilterConfig filterConfig) throws ServletException {
}
#Override
public void destroy() {
}
}

java.lang.IllegalStateException when trying to navigate between two Java EE applications

Basically i have a enterprise jsf application which shows some services to the user.
Different departments of the enterprise host different applications on single webserver and links are provided in our application to access them.
I have a Servlet named RedirectServlet in my application through which i am redirecting all the requests to different applications.The following is my redirectservlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
LOGGER.debug("In doGet()");
try{
if(request.getParameter("URL") != null){
LOGGER.debug("URL Found redirecting forward");
String redirectUrl = request.getParameter("URL");
response.sendRedirect(redirectUrl);
}
}catch(NullPointerException e){
LOGGER.debug("URL not found setting new session parameters & redirecting forward");
HttpSession session = request.getSession(true);
try {
response.sendRedirect(properties.getProperty(REDIRECTURL, true));
} catch (Exception e1) {
LOGGER.debug("Expcetion with propertiesfile: ",e1);
}
}
}
What i do above is if a link is clicked(URL parameter is present) i redirect to specific application, otherwise i just create a new session of my application and redirect to my application homepage.
when the user logsout from any other application, i am redirecting back to my application
This is how i am redirecting back to my application
public void Logout(){
LOGGER.debug("In LogOut");
try
{
HttpServletRequest req = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
HttpServletResponse res = (HttpServletResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse();
HttpSession session = req.getSession(false);
LOGGER.debug("report session id:" + session.getId());
res.sendRedirect(REDIRECTURL);
session.invalidate();
}catch(IllegalStateException e){
LOGGER.debug("Exception in LogOut", e);
}
catch (IOException e){
LOGGER.debug("Exception in LogOut", e);
}
}
i am getting the following server error message at res.sendRedirect line in the above code
HTTP Status 500 -
type Exception report
message
description The server encountered an internal error () that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: Cannot forward after response has been committed
javax.faces.webapp.FacesServlet.service(FacesServlet.java:221)
root cause
java.lang.IllegalStateException: Cannot forward after response has been committed
org.apache.myfaces.context.servlet.ServletExternalContextImpl.dispatch(ServletExternalContextImpl.java:368)
org.apache.myfaces.trinidad.context.ExternalContextDecorator.dispatch(ExternalContextDecorator.java:44)
org.apache.myfaces.trinidad.context.ExternalContextDecorator.dispatch(ExternalContextDecorator.java:44)
org.apache.myfaces.trinidadinternal.context.FacesContextFactoryImpl$OverrideDispatch.dispatch(FacesContextFactoryImpl.java:267)
org.apache.myfaces.view.jsp.JspViewDeclarationLanguage.buildView(JspViewDeclarationLanguage.java:94)
org.apache.myfaces.lifecycle.RenderResponseExecutor.execute(RenderResponseExecutor.java:66)
org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:239)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:191)
This is how we are managing session between applications
When the user first login to our application, we store in the some details in DB and after that every applications checks in the DB for that details.
Please somebody help how to solve this.This is time critical
Both the applications are using JSF 1.2 and Apache Trinidad.
The above exception is gone when i added the following line in Logout() method above
FacesContext.getCurrentInstance().responseComplete();
Here is my modified Logout() method
public void Logout(){
LOGGER.debug("In LogOut");
try
{
HttpServletRequest req = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
HttpServletResponse res = (HttpServletResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse();
HttpSession session = req.getSession(false);
LOGGER.debug("report session id:" + session.getId());
session.invalidate();
res.sendRedirect(REDIRECTURL);
FacesContext.getCurrentInstance().responseComplete();
}catch(IllegalStateException e){
LOGGER.debug("Exception in LogOut", e);
}
catch (IOException e){
LOGGER.debug("Exception in LogOut", e);
}
}
session.invalidate();
res.sendRedirect(REDIRECTURL);
Try this out. It may solve your problem.

Resources