Spring security using xml based http authentication

I am trying to implement spring security in my project, my requirements are

The first user will log in with the url that will generate the passcode -

http://localhost:8181/SpringSecurity/login

      

After successful login, I pushed the sqlired enabled API call like -

http://localhost:8181/SpringSecurity/admin with secured key generated by login method

      

I am using crome postman to access the API

Although I am logged with a user having ROLE_ADMIN, but still it does not allow me to access protected APIs

my web.xml

 <?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee     
 http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

<!-- The definition of the Root Spring Container shared by all Servlets 
    and Filters -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>

<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- Processes application requests -->
<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>appServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/spring/spring-security.xml         
    </param-value>
</context-param>

<!-- Spring Security -->
<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>


</web-app>

      

servlet-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">

<mvc:annotation-driven/>

<mvc:resources mapping="/resources/**" location="/resources/" />

<bean
    class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/views/" />
    <property name="suffix" value=".jsp" />
</bean>

<bean id="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">

    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost:3306/test" />
    <property name="username" value="root" />
    <property name="password" value="root" />
</bean>

<bean id="sessionFactory"
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan" value="com.ha.**"/>     
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
            <prop key="hibernate.show_sql">false</prop>
        </props>
    </property>
</bean>

<bean id="txManager"
    class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="persistenceExceptionTranslationPostProcessor"
    class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

<bean id="savedRequestAwareAuthenticationSuccessHandler"
    class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
    <property name="targetUrlParameter" value="targetUrl" />
</bean>

<context:component-scan base-package="com.ha.**" />

<bean id="jsonConverter"
    class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
    <property name="prefixJson" value="false" />
    <property name="supportedMediaTypes" value="application/json" />
</bean>

<import resource="../spring-security.xml"/>

      

spring-security.xml

<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">

<security:global-method-security secured-annotations="enabled"/>

<http auto-config="true">
    <intercept-url pattern="/admin**" access="ROLE_ADMIN" />
    <custom-filter ref="tokenProcessingFilter" after="FORM_LOGIN_FILTER" />
</http>

<beans:bean
    class="com.ha.security.AuthenticationTokenAndSessionProcessingFilter"
    id="tokenProcessingFilter">
    <beans:constructor-arg name="principal" value="ANONYMOUS" />
    <beans:constructor-arg name="authority" value="anonymousUser" />
    <beans:constructor-arg name="tokenStore" ref="inMemoryTokenStore" />
</beans:bean>

<beans:bean class="com.ha.security.InMemoryTokenStore" id="inMemoryTokenStore" />

<authentication-manager>
    <authentication-provider>
        <user-service>
            <user name="hr" password="123456" authorities="ROLE_USER" />
        </user-service>
    </authentication-provider>
</authentication-manager>

      

Controller file

      package com.ha.security;

  import java.util.ArrayList;
  import java.util.List;

  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.http.HttpStatus;
  import org.springframework.http.MediaType;
  import org.springframework.security.access.annotation.Secured;
  import org.springframework.security.core.GrantedAuthority;
  import org.springframework.security.core.authority.SimpleGrantedAuthority;
  import org.springframework.security.core.userdetails.User;
  import org.springframework.stereotype.Controller;
  import org.springframework.util.StringUtils;
  import org.springframework.web.bind.annotation.RequestBody;
  import org.springframework.web.bind.annotation.RequestMapping;
  import org.springframework.web.bind.annotation.RequestMethod;
  import org.springframework.web.bind.annotation.ResponseBody;
  import org.springframework.web.bind.annotation.ResponseStatus;

  import com.google.gson.Gson;
  import com.google.gson.GsonBuilder;
  import com.ha.model.UserEntity;
  import com.ha.services.IUserService;

  /**
   * Handles requests for the application home page.
   */
  @Controller
  public class HomeController {

     @Autowired
     private InMemoryTokenStore tokenStore;

     @Autowired
     IUserService userServices;

  /*    @RequestMapping(value = { "/" }, method = RequestMethod.GET)
     public String welcomePage() {
        return "index";

     }  */

     @RequestMapping(value = { "/", "/welcome**" }, method = RequestMethod.GET)
     @Secured("ROLE_ADMIN")
     public @ResponseBody String defaultPage() {

         List<UserEntity> userEntity = userServices.getUsersList();
         GsonBuilder builder = new GsonBuilder();
          Gson gson = builder.create();
          return gson.toJson(userEntity);
     }

     @RequestMapping(value = "/admin", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
     @ResponseStatus(value = HttpStatus.OK)
     @ResponseBody
     public ResponseDto adminPage() {
        return new ResponseDto("Can Access Admin");
     }

     @RequestMapping(value = "/login", method = RequestMethod.POST, produces = { MediaType.APPLICATION_JSON_VALUE })
     @ResponseStatus(value = HttpStatus.OK)
     @ResponseBody
     public ResponseDto login(@RequestBody UserLoginDto loginDto) {
        String userName = loginDto.getUserName();
        String password = loginDto.getPassword();   
        if (StringUtils.hasText(userName) && StringUtils.hasText(password)
              && userServices.validateAdminUser(loginDto)) {
           ArrayList<GrantedAuthority> objAuthorities = new ArrayList<GrantedAuthority>();
           SimpleGrantedAuthority objAuthority = new SimpleGrantedAuthority(
                 "ROLE_ADMIN");
           objAuthorities.add(objAuthority);
           User user = new User(userName, password, objAuthorities);
           return new ResponseDto(this.tokenStore.generateAccessToken(user));
        } else {
           return new ResponseDto("Not Valid User");
        }
     }
  }

      

AuthenticationTokenAndSessionProcessingFilter

package com.ha.security;
import java.io.IOException;
import java.util.List;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.GenericFilterBean;

public class AuthenticationTokenAndSessionProcessingFilter extends
    GenericFilterBean {

private final InMemoryTokenStore tokenStore;

private final Object principal;
private final List<GrantedAuthority> authorities;

public AuthenticationTokenAndSessionProcessingFilter(
        InMemoryTokenStore tokenStore, String authority, String principal) {
    this.tokenStore = tokenStore;
    this.principal = principal;
    this.authorities = AuthorityUtils.createAuthorityList(authority);
}

@Override
public void doFilter(ServletRequest request, ServletResponse response,
        FilterChain chain) throws IOException, ServletException {
    if (!(request instanceof HttpServletRequest)) {
        throw new RuntimeException("Expecting a HTTP request");
    }

    HttpServletRequest httpRequest = (HttpServletRequest) request;

    String authToken = null;
    UserDetails objUserDetails = null;
    if (StringUtils.hasText(httpRequest.getHeader("Authorization"))) {
        authToken = httpRequest.getHeader("Authorization");
        objUserDetails = this.tokenStore
                .readAccessToken(authToken);
    }
    setAuthentication(objUserDetails, httpRequest);
    chain.doFilter(request, response);

}

private void setAuthentication(UserDetails objUserDetails,
        HttpServletRequest request) {
    UsernamePasswordAuthenticationToken authentication = null;
    if (null != objUserDetails) {
        authentication = new UsernamePasswordAuthenticationToken(
                objUserDetails, null, objUserDetails.getAuthorities());
        authentication.setDetails(new WebAuthenticationDetailsSource()
                .buildDetails(request));
        SecurityContextHolder.getContext()
                .setAuthentication(authentication);
    } else {
        authentication = new UsernamePasswordAuthenticationToken(
                this.principal, null, this.authorities);
        SecurityContextHolder.getContext()
                .setAuthentication(authentication);
    }
}
}

      

+3


source to share


2 answers


I believe you need to use the hasRole method

<intercept-url pattern="/admin**" access="hasRole('ROLE_ADMIN')" />

      



And also I noticed that you only have one user in your list of users with a role "ROLE_USER"

, hopefully you added an admin user.

0


source


Thanks for your support, the issue has been resolved now and that was with importing the security action style. I imported securty XML file several times.

I had import security in

web.xml

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/spring/spring-security.xml         
    </param-value>
</context-param>

      

and also in the spring-context.xml file



<import resource="../spring-security.xml"/>

      

due to the fact that multiple instances are creted ofMemoryTokenStore and when checking it validates the user's token with another.

After removing the entry from spring-context.xml and adding the following qualifer to the HomeController, my code works fine

@Qualifier("inMemoryTokenStore")
private InMemoryTokenStore tokenStore;

      

Thanks evertybuddy .... :)

0


source







All Articles