Filters and redirects are not my strong point.
I have Shiro set up and working in Spring except that I'd like to return an error message on an invalid login while staying of the same page. So I'm causing a invalid login. I've got ShiroFilterFactoryBean set with a property that should send it to /ldapLoginErr which then I map to login.jsp and then process in a error function in my Controller. But I'm getting a 404 and the url is pointing to my base url instead /ldapLoginErr or /ldapLogin.
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<mvc:view-controller path="/ldapLogin" view-name="ldapLogin" />
<mvc:view-controller path="/ldapLoginSuccess" view-name="ldapLogin" />
<mvc:view-controller path="/ldapLoginErr" view-name="ldapLogin" />
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<property name="loginUrl" value="/ldapLogin"/>
<property name="unauthorizedUrl" value="/ldapLogin"/>
<property name="successUrl" value="/ldapLogin"/>
<property name="filterChainDefinitions">
<value>
[urls]
/** = ssl[8443],authc, customAuthFilter
[main]
/logout = logout
</value>
</property>
</bean>
@RequestMapping(value = "/ldapLogin", method = RequestMethod.GET)
public ModelAndView login(Model model, HttpSession session){
logger.debug("start login controller function");
ModelAndView mav = new ModelAndView();
return mav;
}
@RequestMapping(value = "/ldapLoginErr", method = RequestMethod.GET)
public ModelAndView loginErr(Model model, HttpSession session){
ModelAndView mav = new ModelAndView();
mav.addObject("errorMessage", msgSrc.getMessage("auth.notauth", null, null, null));
return mav;
}
@RequestMapping(value = "/ldapLoginSuccess", method = RequestMethod.GET)
public ModelAndView loginSuccess(Model model, HttpSession session){
}
The following didn't work either:
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<property name="loginUrl" value="/ldapLogin"/>
<property name="unauthorizedUrl" value="/ldapLoginErr"/>
<property name="successUrl" value="/ldapLoginSuccess"/>
Thanks for any help
That seems convoluted.
Create a controller that had a GET and POST endpoint mapped to /login
GET returns the view for the login page.
POST handles the call to shiro login.
Authc filter
<bean id="authc" class="org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter">
<property name="loginUrl" value="/login"/>
</bean>
Filter chain def
<property name="filterChainDefinitions">
<value>
/login = authc
/logout = logout
/secure/** = authc
</value>
</property>
Controller
@RequestMapping(method = RequestMethod.GET)
public ModelAndView view() {
return new ModelAndView(view);
}
@RequestMapping(method = RequestMethod.POST)
public ModelAndView login(HttpServletRequest req, HttpServletResponse res, LoginForm loginForm) {
try {
Subject currentUser = SecurityUtils.getSubject();
currentUser.login(new UsernamePasswordToken(loginForm.getUsername(), loginForm.getPassword());
WebUtils.redirectToSavedRequest(req, res, fallBackUlr);
return null; //redirect
} catch(AuthenticationException e) {
ModelAndView mav = new ModelAndView(view)
mav.addObject("errorMessage", "error");
return mav;
}
}