Liferay : How can I land to custom url on signout - liferay

I'm not sure if I can achieve this by simply configuration or I need to override LogoutAction for it.
I've configured multiple organisation and each organisation has there own site which I want to navigate to my custom url for different site instead of default url on logout from liferay.
[EDITED]
I want to navigate on different url for each site, not a common url.
Thanks

For this you can use default.logout.page.path property (in portal-ext.properties file)
default.logout.page.path=
#default.logout.page.path=/web/guest/logout

I think you can achieve this by overriding LogoutPostAction through a hook.
Define your LogoutPostAction class in portal.properties of your hook:
logout.events.post=com.my.action.MyLogoutPostAction
Here is a sample code for the class to redirect to your desired page:
public class MyLogoutPostAction 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 {
long groupId = PortalUtil.getScopeGroupId(httpReq);
// code to fetch the Group
// ....
// ....
//
String postLogoutURL = "create your own URL";
// if required: add a parameter
postLogoutURL = HttpUtil.setParameter(postLogoutURL, "my_param", "my_param_value");
// redirect to that URL
response.sendRedirect(postLogoutURL);
}
}
The only thing that can be a road block with this approach would be if Liferay has lost context of the current group from which the user was logged-out. I have not tested the code.

Related

Java - Spring MVC - Redirect to route without button/change url dynamically

Please excuse me for my bad english.
This is my problem using Spring MVC:
Let assume that a user is clicking on a button and arrived to a route called "/randomRoute".
I want him to have the possibility to keep doing his job (for example filling a form). About a certain amount of time (represented by the Thread.sleep in the thread), and whatever he did before, I want him to be redirected to a new route called "/newRandomRoute".
I thought about using Thread.run so that the user can continue his work until the delay is done but I don't know how to implement the redirect to the new route.
Is that possible with Spring? Or is there a way to change the url after the Thread.sleep method?
If you want more precision (I am trying to do something on the "Go to "newRandomRoute" page" comment:
#Controller
#RequestMapping("/home")
public class Chat {
#GetMapping("/randomRoute")
public String displayRandomRoute() {
new Thread() {
#Override
public void run() {
try {
Thread.sleep(5000);
// Go to "/newRandomRoute" newPage
} catch (Exception e) {}
}
}.start();
return "page";
}
#GetMapping("/newRandomRoute")
public String displayNewRandomRoute() {
return "newPage";
}
}
Thanks for your help :)

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?.

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);
}
}

Specific TableController name not working

I have an extremely odd error and wondered if anyone knew the reason for this.
When I create a new DataObject and TableController called Content and ContentController respectively, it doesn't register the tablecontroller and the help documentation it automatically generates has lost its styling.
I can't connect to the controller at all but all other controllers work as expected.
If I just rename it to DataController and that's just the name of the controller, not the dataobject everything works perfectly.
Is ContentController a reserved word of some kind or is this just specifically happening on my machine?
public class DataController : TableController<Content>
{
protected override void Initialize(HttpControllerContext controllerContext)
{
base.Initialize(controllerContext);
MobileContext context = new MobileContext();
DomainManager = new EntityDomainManager<Content>(context, Request, Services);
}
// GET tables/Content
public IQueryable<Content> GetAllContent()
{
return Query();
}
// GET tables/Content/48D68C86-6EA6-4C25-AA33-223FC9A27959
public SingleResult<Content> GetContent(string id)
{
return Lookup(id);
}
// PATCH tables/Content/48D68C86-6EA6-4C25-AA33-223FC9A27959
public Task<Content> PatchContent(string id, Delta<Content> patch)
{
return UpdateAsync(id, patch);
}
// POST tables/Content/48D68C86-6EA6-4C25-AA33-223FC9A27959
public async Task<IHttpActionResult> PostContent(Content item)
{
Content current = await InsertAsync(item);
return CreatedAtRoute("Tables", new { id = current.Id }, current);
}
// DELETE tables/Content/48D68C86-6EA6-4C25-AA33-223FC9A27959
public Task DeleteContent(string id)
{
return DeleteAsync(id);
}
}
An MVC project will create an application directory called Content. This will override your route mapping to the ContentController.
You can get around this if desired through changing RouteMaps and other trickery although probably the simpliest answer is to change the name of the controller...

How to handle HTTP 403 with Spring Security 3.0.x

I'm facing a little issue with Spring Security 3.0.x (3.0.2 in particular at the moment). The whole application I'm working on is working perfectly except when someone who doesn't have the authorities tries to log on.
When it occurs, the users is redirected to the "welcome" page, since his username/password are valid, and he receive a cute white page with this : "Error 403: Access is denied"
So, I've been looking on the net trying to find how this behavior can be handled. So far I've come to the conclusion, please correct me if I'm wrong, that it is managed by the ExceptionTranslationFilter. But I don't quite understand how to make any good use of this information.
I've tryied to edit my SecurityContext.xml to add a access-denied-handler tag to my http tag, but it doesn't work. Do I need to add more than this tag to make it work? Is there any other possibilities to make my application more user-friendly?
Edit : I would like to redirect to a page, let's says 403.html, for example.
Sincerly,
Thanks
I still don't get why you had to implement your own access handler... I have currently faced same task:
<security:access-denied-handler error-page="/accessDenied"/> - works like charm.
Don't forget to specify handler in your Controller:
#RequestMapping(value = "/accessDenied")
public String accessDenied() {
return "accessDenied"; // logical view name
}
Update for Spring Boot(2014 Oct):
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.exceptionHandling().accessDeniedHandler(customHandler) OR .accessDeniedPage("/somePage.html").and
.formLogin()
.failureHandler(ajaxAuthenticationFailureHandler)}
Nowadays we don't really return views for such task since angular js kicks in so you can use your failure/success handler and return tailored JSON responses. For us it was sufficient to use failure handler but you get to choose where you want your control to kick in. We generally don't use view resolvers as there are UI tiles frameworks(such as angular partials) able to construct pieces into single page for you. Html pieces are stored on the server and served simply as static resources.
Lets play with Embedded Tomcat to achieve similar behavior to web.xml !
#Configuration
#EnableAutoConfiguration
public class ApplicationWebXml extends SpringBootServletInitializer {
private static final Logger LOGGER = LoggerFactory.getLogger(Application.class);
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.profiles(addDefaultProfile())
.showBanner(false)
.sources(Application.class);
}
//required for container customizer to work, the numerous tutorials didn't work for me, so I simply tried overriding the default one
#Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
return tomcat;
}
#Bean
public EmbeddedServletContainerCustomizer containerCustomizer(
) {
return new EmbeddedServletContainerCustomizer() {
#Override
public void customize(ConfigurableEmbeddedServletContainer container) {
TomcatEmbeddedServletContainerFactory containerFactory = (TomcatEmbeddedServletContainerFactory) container;
containerFactory.setSessionTimeout(1); // just for your interest, remove as necessary
containerFactory.addErrorPages(new ErrorPage(HttpStatus.FORBIDDEN,"/views/accessDenied.html"),
new ErrorPage(HttpStatus.NOT_FOUND,"/views/notFound.html"));
containerFactory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
#Override
public void customize(Connector connector) {
connector.setPort(8082);// just for your interest, remove as necessary
}
});
}
};
}
}
A cleaner way to handle error redirects is to use the <error-page> and <error-code> tags in your web.xml. See below for an example:
<!-- Custom 403 Error Page -->
<!--
NOTE: Security will throw this error when a user has been authenticated successfully
but lacks the permissions to perform the requested action.
-->
<error-page>
<error-code>403</error-code>
<location>/403.jsp</location>
</error-page>
This block of code will redirect to the specified location whenever it encounters the specified error code.
This eliminates the need for authorization code inside your application logic.
I've found how to do this. By implementing the AccessDeniedHandler interface and the corresponding handle method I can, easily, control the way the Http 403 error is handled.
This way, you can add various items in the session and then intercept them on your jsp.
The xml file then looks like this :
<sec:http>
<!-- lots of urls here -->
<sec:access-denied-handler ref="accessDeniedHandler" />
<sec:anonymous/>
</sec:http>
<bean id="accessDeniedHandler" class="foo.bar.CustomAccessDeniedHandler">
<property name="accessDeniedUrl" value="403.html" />
</bean>
The java class :
package foo.bar;
public class CustomAccessDeniedHandler implements org.springframework.security.web.access.AccessDeniedHandler {
private String accessDeniedUrl;
public CustomAccessDeniedHandler() {
}
public CustomAccessDeniedHandler(String accessDeniedUrl) {
this.accessDeniedUrl = accessDeniedUrl;
}
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
response.sendRedirect(accessDeniedUrl);
request.getSession().setAttribute("CustomSessionAttribute", "value here");
}
public String getAccessDeniedUrl() {
return accessDeniedUrl;
}
public void setAccessDeniedUrl(String accessDeniedUrl) {
this.accessDeniedUrl = accessDeniedUrl;
}
}
And a jsp example :
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:if test="${!empty CustomSessionAttribute}">
<br/>
ACCESS IS DENIED
<br/>
</c:if>
<!-- other stuff down here -->
The way to make this work is to define a handler in your entry point:
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
#Override
public void commence(HttpServletRequest request, HttpServletResponse response, org.springframework.security.core.AuthenticationException authException) throws IOException, ServletException {
if (authException != null) {
// you can check for the spefic exception here and redirect like this
response.sendRedirect("403.html");
}
}
}
You can define this as your entry point by setting this as you entry point in the xml config file:
<http entry-point-ref="customAuthenticationEntryPoint">
...
</http>
You have checked the tag in an application and to me it seems to work.
<sec:access-denied-handler error-page="/handle403Url" />
where handle403Url I want to call to handle this error (for example to show an error).
Don't forget that you have to allow this url in the filters so it can be reached by this user authority, so in the start of the flters you have to add something like this:
<sec:intercept-url pattern="/handle403Url" filters="none" />

Resources