How to prioritize interceptors in Spring web mvc - spring

I have three interceptors in my application and i just want to prioritize them, actually i want to auto login my application from another application via query params.
This interceptor is validating the user session if user doesn't have valid session then it will redirect user to login page and it is working fine.
public class ValidateSessionInterceptor extends HandlerInterceptorAdapter {
private Logger log = Logger.getLogger(getClass());
#Value("${http.port}")
private int httpPort;
#Value("${https.port}")
private int httpsPort;
#Value("${use.ssl}")
private boolean useSsl;
//before the actual handler will be executed
public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
if(session.getAttribute("user")==null){
String forwardTo = (String) request.getAttribute("org.springframework.web.servlet.HandlerMapping.pathWithinHandlerMapping");
String params = "";
if(request.getQueryString()!=null){
params = "?" + request.getQueryString();
}
String url = getApplicationUrl(request,useSsl)+forwardTo+params;
log.info("redirect url: " + request.getContextPath()+"/login/index.mars?forwardTo="+URLEncoder.encode(url, "UTF-8"));
response.sendRedirect(request.getContextPath()+"/login/index.mars?forwardTo="+URLEncoder.encode(url, "UTF-8"));
return false;
}else{
Map<String,String> owners = new LinkedHashMap<String,String>();
owners.put("NA", "NA");
owners.put("AK", "AK");
request.setAttribute("ownerList", owners);
}
return true;
}
private String getApplicationUrl(HttpServletRequest request,boolean useSsl){
if(useSsl){
return "https://"+request.getServerName()+":"+httpsPort+request.getContextPath();
}else{
return "http://"+request.getServerName()+":"+httpPort+request.getContextPath();
}
}
}
This is being called by another application and passing autoUsr and autoPwd parameters to auto logged in application.
public class AutoLoginInterceptor extends HandlerInterceptorAdapter{
private final Logger log = Logger.getLogger(getClass());
#Autowired
public UserService userService;
#Autowired
public WebService webService;
public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws IOException, UserException {
HttpSession session = request.getSession();
if(session.getAttribute("user")==null){
String forwardTo = request.getParameter("forwardTo");
if(forwardTo!=null && !forwardTo.equals("")){
User user = checkLoginCrendential(forwardTo);
log.info("user-> " + user);
this.webService.buildWebService(request);
if(userService.login(request, user)){
session.setAttribute("user", user);
return true;
}
}
}
return true;
}
public User checkLoginCrendential(String url){
String decURL;
User user = new User();
try
{
decURL = URLDecoder.decode(url,"utf-8");
String params[] = (decURL.split("\\?")[1]).split("&");
String loginParams[] = {"autoUsr","autoPwd"};
for(String lgnParam : loginParams){
for(int i = 0 ; i < params.length ; i++){
String param[] = params[i].split("=");
if(lgnParam.equals(param[0])){
if(param.length > 1){
if(lgnParam.equals("autoUsr")){
user.setUsername(param[1]);
}else if(lgnParam.equals("autoPwd")){
user.setPassword(param[1]);
}
}else{
if(lgnParam.equals("autoUsr")){
user.setUsername("");
}else if(lgnParam.equals("autoPwd")){
user.setPassword("");
}
}
}
}
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return user;
}
}

You can use tag to order interceptors in XXX-servlet.xml. For example :
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="ValidateSessionInterceptor" />
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="AutoLoginInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
interceptors will be called by order

Related

Map LDAP groups to OAuth2 UserDetails in Spring Boot web app

After failed attempts to get CAS Single Sign Out working, we decided to try out OAuth2 using OpenID Connect with our Spring Boot web apps. Now we only need OAuth for SSO and to provide authentication - we're not storing username/password in a db or anything. We are using Google LDAP to grant authorities. I cannot find any solid example of using Google LDAP for authorities with OAuth2. My OAuth2 code is pretty simple so far. Here's my WebSecurityConfig so far:
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests(authorizeRequests -> authorizeRequests
.mvcMatchers("/home").permitAll()
.anyRequest().authenticated())
.oauth2Login(oauthLogin -> oauthLogin.permitAll());
}
and one of my endpoints that works:
#GetMapping("/user/me")
public String userDetails(#AuthenticationPrincipal OAuth2User user) {
Map<String, Object> attributes = user.getAttributes();
String username = (String) attributes.get("email");
return username;
}
Now here is what I used with my CAS and LDAP config. This block of code would pull all LDAP groups and map them to roles using SimpleGrantedAuthority. I've tried a ton of different configs, but nothing has worked.
private LdapContext getLdapReadContext(){
LdapContext ctx = null;
try{
Hashtable<String,String> env = new Hashtable<>();
env.put(Context.INITIAL_CONTEXT_FACTORY,ldapCtxFactory);
env.put(Context.SECURITY_AUTHENTICATION,"Simple");
env.put(Context.SECURITY_PRINCIPAL,ldapUsername);
env.put(Context.SECURITY_CREDENTIALS,ldapPassword);
env.put(Context.PROVIDER_URL,ldapURL);
ctx = new InitialLdapContext(env,null);
}catch(NamingException e){
e.printStackTrace();
}
return ctx;
}
public List<String> Groups(LdapContext ctx, AttributePrincipal principal){
String uid = "uid";
List<String> groups = new LinkedList<>();
NamingEnumeration answer = null;
if(principal!=null){
Map attributes =principal.getAttributes();
if(attributes.get(uid)!=null){
uid=attributes.get(uid).toString();
try{
SearchControls constraints = new SearchControls();
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
String searchFilter = "(&(objectClass=groupOfNames)(member=uid="+uid+","+ldapBase+"))";
String[] attrIDs = {"cn"};
constraints.setReturningAttributes(attrIDs);
answer = ctx.search(ldapGroupBase,searchFilter,constraints);
while (answer.hasMore()){
Attributes attrs = ((SearchResult)answer.next()).getAttributes();
groups.add(attrs.get("cn").toString());
}
}catch(Exception ignored){
}finally{
if (answer !=null){
try{
answer.close();
}catch(Exception ignored){
}
}
if (ctx != null){
try{
ctx.close();
}catch(Exception ignored){
}
}
}
}
}
if (groups.isEmpty()){
groups.add("STUDENT");
}
return groups;
}
#Override
public UserDetails loadUserDetails (#Autowired Authentication authentication) throws UsernameNotFoundException {
CasAssertionAuthenticationToken casAssertionAuthenticationToken = (CasAssertionAuthenticationToken) authentication;
AttributePrincipal principal = casAssertionAuthenticationToken.getAssertion().getPrincipal();
Map attributes = principal.getAttributes();
String user = (String)attributes.get("username");
String email = (String)attributes.get("email");
String fname = (String)attributes.get("fname");
String lname = (String)attributes.get("lname");
String VNumber = (String)attributes.get("UDC_IDENTIFIER");
String uid = (String)attributes.get("uid");
String role = "user";
String username = authentication.getName();
List<String> grouplist = null;
grouplist = Groups(getLdapReadContext(), principal);
Collection<SimpleGrantedAuthority> collection = new ArrayList<SimpleGrantedAuthority>();
for (int i =0; i<grouplist.size(); i++) {
collection.add(new SimpleGrantedAuthority((grouplist.get(i)).substring(4)));
}
return new User(username, "",collection);
}

HttpSession attribute getting removed abnormally after adding

*After I add a session attribute using
WebUtils.setSessionAttribute(request, VBWebConstants.SESSION_ORDER_BEAN,sellerDetails);
#RequestMapping(value="/minasidor/step1",method=RequestMethod.GET)
public ModelAndView step1(HttpServletRequest request,HttpSession session){
if(logger.isTraceEnabled())logger.trace("VbSellerController ::: step1 ::: start");
if(logger.isDebugEnabled())logger.debug("[Order Step1] [Start]");
ModelAndView mav=new ModelAndView("vz-new/mina-sidor/v-orderstep1");
LoginBean user = (LoginBean) WebUtils.getSessionAttribute(request, VBWebConstants.SESSION_USER);
mav.addObject("submenu",3);
if(!checkOrderLifeCycle()){
mav.addObject("orderNotAllowed", false);
return mav;
}
try{
String orderValue = "";
orderValue = InMemoryCache.getCaProperty(PropertyEnum.MIN_ORDER_VALUE.getDatabasekey());
int minimumOrderValue = CawebUtil.isInt(orderValue);
CpSellerDetails sellerDetails=vbOrderService.getStep1Data(user.getGrp_seller_id(),user.getCatalogue_id());
if(sellerDetails != null){
mav.addObject("productlist",sellerDetails.getSellerList());
mav.addObject("totalValue",sellerDetails.getTotalOrderValue());
mav.addObject("allowedfororder",sellerDetails.getTotalOrderValue() > minimumOrderValue);
// mav addobject add discount details Discount Object ArrayList
WebUtils.setSessionAttribute(request, VBWebConstants.SESSION_ORDER_STEP_COMPLETED,"step1");
WebUtils.setSessionAttribute(request, VBWebConstants.SESSION_ORDER_BEAN,sellerDetails);
}else{
mav.addObject("allowedfororder",false);
WebUtils.setSessionAttribute(request, VBWebConstants.SESSION_ORDER_STEP_COMPLETED,null);
}
}catch(DataNotFoundException e){
logger.trace("Exception in retrieving data for step1",e);
if(logger.isDebugEnabled())logger.debug("[Order Step1 Exception]",e);
}
if(logger.isTraceEnabled())logger.trace("VbSellerController ::: step1 ::: end");
if(logger.isDebugEnabled())logger.debug("[Order Step1] [end]");
return mav;
}
Within this step1 method the VBWebConstants.SESSION_ORDER_BEAN session attribute is getting removed instantly after the step1() method finishes executing where as the other session attributes remains the same.When i debug the below Http Listener class
public class MyHttpSessionListener implements HttpSessionListener,HttpSessionAttributeListener {
public static final Logger logger = Logger.getLogger(MyHttpSessionListener.class);
public void sessionCreated(HttpSessionEvent se) {
//String ipAddr = ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest().getRemoteAddr();
HttpSession session = se.getSession();
if(logger.isDebugEnabled()){
StringBuilder sbuilder = new StringBuilder();
sbuilder.append("\n").append("----------- Session Created -------------- ");
Enumeration<String> sessionAttrs = session.getAttributeNames();
while (sessionAttrs.hasMoreElements()) {
String name = sessionAttrs.nextElement();
sbuilder.append("\n").append(" session created ").append(name);
}
sbuilder.append("\n").append(" session created time "+ CawebUtil.getTimeStampInString(new Timestamp(session.getCreationTime())));
sbuilder.append("\n").append("---------------------------------------------------- ").append("\n");
logger.debug(sbuilder.toString());
}
}
public void sessionDestroyed(HttpSessionEvent se) {
HttpSession session = se.getSession();
if(logger.isDebugEnabled()){
try{
String ipAddr = ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest().getRemoteAddr();
logger.debug(" session destroyed " +ipAddr);
}catch (Exception e) {
}
}
}
public void attributeAdded(HttpSessionBindingEvent se) {
String ipAddr = ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest().getRemoteAddr();
HttpSession session = se.getSession();
if(logger.isDebugEnabled()){
StringBuilder sbuilder = new StringBuilder();
sbuilder.append("\n").append("----------- Attribute added -------------- from ").append(ipAddr);
sbuilder.append("\n").append(" session max inactive time "+ session.getMaxInactiveInterval());
sbuilder.append("\n").append(" session id "+ session.getId());
sbuilder.append("\n").append(" session attribute added "+ se.getName()).append(" = ").append(se.getValue());
sbuilder.append("\n").append(" session created time "+ CawebUtil.getTimeStampInString(new Timestamp(session.getCreationTime())));
}
}
public void attributeRemoved(HttpSessionBindingEvent se) {
if(logger.isDebugEnabled() ){
StringBuilder sbuilder = new StringBuilder();
sbuilder.append("\n").append("----------- Attribute removed -------------- from ");//.append(ipAddr);
sbuilder.append("\n").append(" session attribute removed "+ se.getName()).append(" = ").append(se.getValue());
}
}
public void attributeReplaced(HttpSessionBindingEvent se) {
if(logger.isDebugEnabled()){
StringBuilder sbuilder = new StringBuilder();
sbuilder.append("\n").append("----------- Attribute replaced -------------- from ");//.append(ipAddr);
sbuilder.append("\n").append(" session attribute "+ se.getName()).append(" = ").append(se.getValue());
}
}
}
I found that the session attribute is getting removed.Checked through the entire code I couldn't find what's the reason...???
Here is the CPSellerDetails class which i try to add to the session there are other 2 session attributes among which one is a string object and other is a bean.could it the size of the class that is the cause for session attribute being removed abnormally
public class CpSellerDetails implements Serializable{
/**
*
*/
private static final long serialVersionUID = -4627284179051380310L;
private List<SellerProduct> sellerList ;
private float totalOrderValue ;
private VbCpInfoBean cpinfoBean;
private Integer orderno;
private float invoiceAmount;
private Date orderedDate;
private ArrayList<DiscountVO> discounts;
private Address billingInfo;
public VbCpInfoBean getCpInfoBean() {
return cpinfoBean;
}
public void setCpInfoBean(VbCpInfoBean infoBean) {
this.cpinfoBean = infoBean;
}
public List<SellerProduct> getSellerList() {
return sellerList;
}
public void setSellerList(List<SellerProduct> sellerList) {
this.sellerList = sellerList;
}
public float getTotalOrderValue() {
return totalOrderValue;
}
public void setTotalOrderValue(float totalOrderValue) {
this.totalOrderValue = totalOrderValue;
}
public float getInvoiceAmount() {
return invoiceAmount;
}
public void setInvoiceAmount(float invoiceAmount) {
this.invoiceAmount = invoiceAmount;
}
public Integer getOrderno() {
return orderno;
}
public void setOrderno(Integer orderno) {
this.orderno = orderno;
}
public Date getOrderedDate() {
return orderedDate;
}
public void setOrderedDate(Date orderedDate) {
this.orderedDate = orderedDate;
}
public ArrayList<DiscountVO> getDiscounts() {
return discounts;
}
public void setDiscounts(ArrayList<DiscountVO> discounts) {
this.discounts = discounts;
}
public Address getBillingInfo() {
return billingInfo;
}
public void setBillingInfo(Address billingInfo) {
this.billingInfo = billingInfo;
}
}*

Spring Security: password don't match with stored one

I have a problem with password hashing. I want to appply sha-256 with salt and 1024 iterations to authenticate my users using Spring Security. But somehow, my password in database dont match those from user input.
Here is my code:
security-context.xml
<beans:bean
id="passwordEncoder"
class="org.springframework.security.authentication.encoding.ShaPasswordEncoder" >
<beans:constructor-arg value="256" />
<beans:property
name="iterations"
value="1024" />
</beans:bean>
<beans:bean class="org.springframework.security.authentication.dao.ReflectionSaltSource" id="saltSource">
<beans:property name="userPropertyToUse" value="id"/>
</beans:bean>
<authentication-manager>
<authentication-provider user-service-ref="userLoginDetails" >
<password-encoder ref="passwordEncoder" >
<salt-source ref="saltSource"/>
</password-encoder>
</authentication-provider>
</authentication-manager>
userLoginDetails
#Transactional(readOnly = true)
public class UserLoginDetails implements UserDetailsService {
private EregDaoFactory daoFactory;
#Autowired
public void setDaoFactory(EregDaoFactory daoFactory) {
this.daoFactory = daoFactory;
}
/**
* Retrieves a user record containing the user's credentials and access.
*/
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException,
DataAccessException {
Logger logger = Logger.getLogger(getClass());
logger.setLevel(Level.ALL);
int userId = Integer.parseInt(username);
UzytkownikDao dao = daoFactory.getUzytkownikDao();
LoggedUser user = null;
Uzytkownik dbUser = null;
try {
dbUser = (Uzytkownik) dao.findById(Integer.parseInt(username));
List<SimpleGrantedAuthority> grants = new ArrayList<SimpleGrantedAuthority>();
Collection<Object> userNames = new ArrayList<Object>();
if (dbUser.getRola() == 'U') {
grants.add(new SimpleGrantedAuthority("ROLE_STUDENT"));
userNames = daoFactory.getUczenDao().getNameAndLastName(userId);
} else if (dbUser.getRola() == 'N') {
grants.add(new SimpleGrantedAuthority("ROLE_TEACHER"));
userNames = daoFactory.getNauczycielDao().getNameAndLastName(userId);
} else if (dbUser.getRola() == 'O') {
grants.add(new SimpleGrantedAuthority("ROLE_PARENT"));
userNames = daoFactory.getOpiekunDao().getNameAndLastName(userId);
}
grants.add(new SimpleGrantedAuthority("ROLE_USER"));
Object[] names = userNames.toArray();
user =
new LoggedUser(username, dbUser.getHaslo(), true, true, true, true, grants,
(String) names[0], (String) names[1], dbUser.getRola());
} catch (Exception e) {
logger.error(e.getLocalizedMessage());
throw new UsernameNotFoundException("Error in retrieving user");
}
return user;
}
}
LoggedUser
package ereg.security.userdetails;
public class LoggedUser extends User {
private static final long serialVersionUID = 1L;
private final String id;
private final String imie;
private final String nazwisko;
private final char rola;
private Date lastSuccessfulLogin;
private String lastKnowIpAddress;
public LoggedUser(String username, String password, boolean enabled, boolean accountNonExpired,
boolean credentialsNonExpired, boolean accountNonLocked,
Collection<? extends GrantedAuthority> authorities, String name, String lastName, char rola) {
super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked,
authorities);
this.imie = name;
this.nazwisko = lastName;
this.rola = rola;
this.id = username;
}
public String getId() {
return id;
}
public String getImie() {
return imie;
}
public String getNazwisko() {
return nazwisko;
}
public char getRola() {
return rola;
}
public Date getLastSuccessfulLogin() {
return lastSuccessfulLogin;
}
public String getFormattedDate() {
if (lastSuccessfulLogin != null) {
return new SimpleDateFormat("dd/MM/yyyy, HH:mm:ss").format(lastSuccessfulLogin);
} else
return null;
}
public String getLastKnowIpAddress() {
return lastKnowIpAddress;
}
public void setLastSuccessfulLogin(Date lastSuccessfulLogin) {
this.lastSuccessfulLogin = lastSuccessfulLogin;
}
public void setLastKnowIpAddress(String lastKnowIpAddress) {
this.lastKnowIpAddress = lastKnowIpAddress;
}
}
And here is the program that hashes passwords:
EncryptAllUsersPasswords
private void encryptPasswords() throws Exception {
OneWayEncryptor encryptor = OneWayEncryptor.getInstance();
appContext =
new FileSystemXmlApplicationContext(
"C:/EclipseWorkSpace/myereg/WebContent/WEB-INF/applicationContext.xml");
ds = (DataSource) appContext.getBean("dataSource");
JdbcTemplate jdbc = new JdbcTemplate(ds);
BigDecimal userId = null;
String password = "";
String encrypted = "";
Map<?, ?> row = new HashMap<Object, Object>();
for (Iterator<?> it = jdbc.queryForList("SELECT id, haslo FROM UZYTKOWNIK").iterator(); it.hasNext();) {
row = (Map<?, ?>) it.next();
userId = (BigDecimal) row.get("ID");
password = (String) row.get("HASLO");
encrypted = encryptor.encrypt(password, userId.toString());
System.out.println(userId.toString());
jdbc.execute("UPDATE UZYTKOWNIK SET haslo = '" + encrypted + "' WHERE id = " + userId);
}
}
public static void main(String[] args) {
EncryptAllUserPasswords encrypt = new EncryptAllUserPasswords();
try {
encrypt.encryptPasswords();
} catch (Exception e) {
e.printStackTrace();
}
}
OneWayEncryptor
public final class OneWayEncryptor {
private static final OneWayEncryptor INSTANCE = new OneWayEncryptor();
private static final int ITERATIONS = 1024;
private static final String ALGORITHM = "SHA-256";
private OneWayEncryptor() {
}
public static OneWayEncryptor getInstance() {
return INSTANCE;
}
public String encrypt(String plaintext, String salt) throws NoSuchAlgorithmException,
UnsupportedEncodingException {
MessageDigest messageDigest = MessageDigest.getInstance(ALGORITHM);
messageDigest.reset();
messageDigest.update(salt.getBytes());
byte[] btPass = messageDigest.digest(plaintext.getBytes("UTF-8"));
for (int i = 0; i < ITERATIONS; i++) {
messageDigest.reset();
btPass = messageDigest.digest(btPass);
}
String encodedPassword = byteToBase64(btPass);
return encodedPassword;
}
private String byteToBase64(byte[] bt) throws UnsupportedEncodingException {
return new String(Base64.encodeBase64(bt));
}
}
I believe that problem lies in the last one... Please help
actually, this worked:
public String encrypt(String plaintext, String salt) throws NoSuchAlgorithmException,
UnsupportedEncodingException {
String pass = plaintext + "{" + salt + "}";
MessageDigest messageDigest = MessageDigest.getInstance(ALGORITHM);
messageDigest.reset();
byte[] btPass = messageDigest.digest(pass.getBytes("UTF-8"));
for (int i = 0; i < ITERATIONS - 1; i++) {
messageDigest.reset();
btPass = messageDigest.digest(btPass);
}
String hashedPass = new BigInteger(1, btPass).toString(16);
if (hashedPass.length() < 32) {
hashedPass = "0" + hashedPass;
}
return hashedPass;
}
can someone tell my why? I mean why when i tried using update(salt) method it didint and when i switch to concate string it did. and i dont mind part with "{salt}", cause that only allows me to generate exactly the same hash as spring does. the thing is that before it generated wrong hash even with given salt. I checked it with sha256 generators. Can someone tell me why it started working after string concatating?

Shiro always redirects me to login.jsp

Here is the config from shiro.ini
shiro.loginUrl = /login.jsp
######### URL CONFIG ################### [urls] /login.jsp = anon /public/login/** = anon /public/app/** = authc
Stripes...
#UrlBinding("/public/app/")
public class CalculatorActionBean implements ActionBean {
.....
}
#UrlBinding("/public/login/")
public class UserAuthenticateBean implements ActionBean {
private static final transient Logger log = LoggerFactory.getLogger(UserAuthenticateBean.class);
private ActionBeanContext context;
private String username;
private String password;
private String message;
public ActionBeanContext getContext() {
return context;
}
public void setContext(ActionBeanContext context) {
this.context = context;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
#DefaultHandler
#DontValidate
public Resolution defaultHander() {
return new ForwardResolution("/login.jsp");
}
public Resolution login() {
Subject currentUser = SecurityUtils.getSubject();
log.info("CU=" + currentUser.toString());
if (!currentUser.isAuthenticated()) {
TenantAuthenticationToken token = new TenantAuthenticationToken(username, password, "jdbcRealm");
//UsernamePasswordToken token = new UsernamePasswordToken("akumar", "ash");
token.setRememberMe(true);
try {
currentUser.login(token);
} catch (UnknownAccountException uae) {
log.info("There is no user with username of " + token.getPrincipal());
} catch (IncorrectCredentialsException ice) {
log.info("Password for account " + token.getPrincipal() + " was incorrect!");
} catch (LockedAccountException lae) {
log.info("The account for username " + token.getPrincipal() + " is locked. "
+ "Please contact your administrator to unlock it.");
} // ... catch more exceptions here (maybe custom ones specific to your application?
catch (AuthenticationException ae) {
//unexpected condition? error?
ae.printStackTrace();
}
}
if (currentUser.isAuthenticated()) {
message = "Success";
} else {
message = "Fail";
}
System.out.println(message);
message += getUsername() + getPassword();
return new ForwardResolution("/logged_in.jsp");
}
}
logged_in.jsp
app
Now if I remove the line
/public/app/** = authc
from shiro.ini, I can access /public/app for a logged in user and guest
If I keep the line, then noone can access the page and it goes back to login.jsp
Driving me nuts!
help!!
Change your urls config to have 'authc' filter the actual login url:
[main]
...
authc.loginUrl = /login.jsp
[urls]
/login.jsp = authc
/public/login/** = anon
/public/app/** = authc
The authc filter is smart enough to know if a request is not authenticated to still let it go through to the underlying page so a user can log in.

spring how to pass values from one page to controller?

I am developing a spring mvc application . I just want to do the following ,
When user clicks on a link , I just want to pass some values from that page to the target Controller of that link.
Is AbstractCommandController will be useful for this ?
Is there any way other than using session attributes ?
You can do it in one of the following ways:
1) Submit Form.
2) Send it as parameters in your URL.
3) Create cusom flash scope for your application:
You can read more about it here:http://goo.gl/nQaQh
In spring MVC there is no Flash Bean scope so you can do it as Interceptor:
Here is the simple code how to use
public class FlashScopeInterceptor implements HandlerInterceptor {
public static final String DEFAULT_ATTRIBUTE_NAME = "flashScope";
public static final String DEFAULT_SESSION_ATTRIBUTE_NAME = FlashScopeInterceptor.class.getName();
public static final int DEFAULT_RETENTION_COUNT = 2;
private String sessionAttributeName = DEFAULT_SESSION_ATTRIBUTE_NAME;
private String attributeName = DEFAULT_ATTRIBUTE_NAME;
private int retentionCount = DEFAULT_RETENTION_COUNT;
/**
* Unbinds current flashScope from session. Rolls request's flashScope to
* the next scope. Binds request's flashScope, if not empty, to the session.
*
*/
#Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
if (request.getSession( false ) != null)
{
request.getSession().removeAttribute( this.sessionAttributeName );
}
Object requestAttribute = request.getAttribute( this.attributeName );
if (requestAttribute instanceof MultiScopeModelMap)
{
MultiScopeModelMap attributes = (MultiScopeModelMap) requestAttribute;
if (!attributes.isEmpty())
{
attributes.next();
if (!attributes.isEmpty())
{
request.getSession( true ).setAttribute( this.sessionAttributeName, attributes );
}
}
}
}
/**
* merge modelAndView.model['flashScope'] to current flashScope
*/
#Override
public void postHandle( HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
if (modelAndView != null)
{
Map<String, Object> modelFlashScopeMap = null;
for (Iterator<Entry<String, Object>> iterator = ((Map<String, Object>) modelAndView.getModel()).entrySet()
.iterator(); iterator.hasNext();)
{
Entry<String, Object> entry = iterator.next();
if (this.attributeName.equals( entry.getKey() ) && entry.getValue() instanceof Map)
{
if (modelFlashScopeMap == null)
{
modelFlashScopeMap = (Map) entry.getValue();
}
else
{
modelFlashScopeMap.putAll( (Map) entry.getValue() );
}
iterator.remove();
}
else if (entry.getKey().startsWith( this.attributeName + "." ))
{
String key = entry.getKey().substring( this.attributeName.length() + 1 );
if (modelFlashScopeMap == null)
{
modelFlashScopeMap = new HashMap<String, Object>();
}
modelFlashScopeMap.put( key, entry.getValue() );
iterator.remove();
}
}
if (modelFlashScopeMap != null)
{
MultiScopeModelMap flashScopeMap;
if (request.getAttribute( this.attributeName ) instanceof MultiScopeModelMap)
{
flashScopeMap = (MultiScopeModelMap) request.getAttribute( this.attributeName );
}
else
{
flashScopeMap = new MultiScopeModelMap( this.retentionCount );
}
flashScopeMap.putAll( modelFlashScopeMap );
request.setAttribute( this.attributeName, flashScopeMap );
}
}
}
/**
* binds session flashScope to current session, if not empty. Otherwise cleans up empty
* flashScope
*/
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession( false );
if (session != null)
{
Object sessionAttribute = session.getAttribute( this.sessionAttributeName );
if (sessionAttribute instanceof MultiScopeModelMap)
{
MultiScopeModelMap flashScope = (MultiScopeModelMap) sessionAttribute;
if (flashScope.isEmpty())
{
session.removeAttribute( this.sessionAttributeName );
}
else
{
request.setAttribute( this.attributeName, flashScope );
}
}
}
return true;
}
}
and then MultiScopeModelMap
public class MultiScopeModelMap extends CompositeMap implements Serializable, MapMutator
{
public MultiScopeModelMap(int num)
{
super();
setMutator( this );
for(int i = 0; i < num; ++i)
{
addComposited( new HashMap() );
}
}
/** Shadows composite map. */
private final LinkedList<Map> maps = new LinkedList<Map>();
#Override
public synchronized void addComposited( Map map ) throws IllegalArgumentException
{
super.addComposited( map );
this.maps.addLast( map );
}
#Override
public synchronized Map removeComposited( Map map )
{
Map removed = super.removeComposited( map );
this.maps.remove( map );
return removed;
}
/**
* Starts a new scope.
* All items added in the session before the previous session are removed.
* All items added in the previous scope are still retrievable and removable.
*/
public void next()
{
removeComposited( this.maps.getFirst() );
addComposited( new HashMap() );
}
public Object put( CompositeMap map, Map[] composited, Object key, Object value )
{
if(composited.length < 1)
{
throw new UnsupportedOperationException("No composites to add elements to");
}
Object result = map.get( key );
if(result != null)
{
map.remove( key );
}
composited[composited.length-1].put( key, value );
return result;
}
public void putAll( CompositeMap map, Map[] composited, Map mapToAdd )
{
for(Entry entry: (Set<Entry>)mapToAdd.entrySet())
{
put(map, composited, entry.getKey(), entry.getValue());
}
}
public void resolveCollision( CompositeMap composite, Map existing, Map added, Collection intersect )
{
existing.keySet().removeAll( intersect );
}
#Override
public String toString()
{
return new HashMap(this).toString();
}
}
Now configure it in xml:
<bean id="flashScopeInterceptor" class="com.vanilla.scopes.FlashScopeInterceptor" />
<bean id="handlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<list><ref bean="flashScopeInterceptor"/></list>
</property>
</bean>
Usage:
#RequestMapping(value="/login.do", method=RequestMethod.POST)
public ModelAndView login(#Valid User user){
ModelAndView mv = new ModelAndView("redirect:result.html");
if (authService.authenticate(user.getUserName(), user.getPassword()))
mv.addObject("flashScope.message", "Success");
//else
mv.addObject("flashScope.message", "Login Failed");
return mv;
}
#RequestMapping(value ="/result.html", method=RequestMethod.GET)
public ModelAndView result(){
ModelAndView mv = new ModelAndView("login/loginAction");
return mv;
}
In JSP the usage is very simple:
${flashScope.message}

Resources