Provide Best Programming Tutorials

Using Spring Security To Protect Your Restful API Endpoint

This article will show how to use Spring Security to protect your Restful API.

Project Structure

SecurityConfig.java

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private DataSource dataSource;
    @Autowired
    private EntryPointUnauthorizedHandler unauthorizedHandler;

    @Autowired
    private MyAccessDeniedHandler accessDeniedHandler;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) {
        try {
            auth.inMemoryAuthentication().withUser("user")
                    .password("user").roles("USER");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Bean
    public AuthenticationTokenFilter authenticationTokenFilterBean() throws Exception {
        AuthenticationTokenFilter authenticationTokenFilter = new AuthenticationTokenFilter();
        authenticationTokenFilter.setAuthenticationManager(authenticationManagerBean());
        return authenticationTokenFilter;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/auth").authenticated()       
                .antMatchers("/admin/**").hasAuthority("admin")   
                .antMatchers("/ADMIN/**").hasRole("ADMIN")    
                .anyRequest().permitAll()      
                .and()
                .exceptionHandling()
                .authenticationEntryPoint(this.unauthorizedHandler)   
                .accessDeniedHandler(this.accessDeniedHandler)      
                .and()
                .csrf()
                .disable()                     
                .sessionManagement()                       
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS); 


        http.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
    }

}

AuthenticationTokenFilter.java

public class AuthenticationTokenFilter extends UsernamePasswordAuthenticationFilter {

    @Value("${token.header}")
    private String tokenHeader;

   
    @Autowired
    private TokenUtils tokenUtils;

    @Autowired
    @Qualifier("userDetailsServiceImpl")
    private UserDetailsService userDetailsService;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String authToken = httpRequest.getHeader(this.tokenHeader);
      
        String username = this.tokenUtils.getUsernameFromToken(authToken);

        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
           
            UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
           
            if (this.tokenUtils.validateToken(authToken, userDetails)) {
                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpRequest));
                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
            if (!userDetails.isEnabled()){
                response.setCharacterEncoding("UTF-8");
                response.setContentType("application/json;charset=UTF-8");
                response.getWriter().print("{\"code\":\"452\",\"data\":\"\",\"message\":\"account in the black list\"}");
                return;
            }
        }

        chain.doFilter(request, response);
    }

}

spring_security.sql

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for role
-- ----------------------------
DROP TABLE IF EXISTS `role`;
CREATE TABLE `role` (
  `role_id` int(2) NOT NULL,
  `role_name` varchar(255) NOT NULL,
  `auth` varchar(255) NOT NULL,
  PRIMARY KEY (`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of role
-- ----------------------------
INSERT INTO `role` VALUES ('1', 'ROLE_USER', 'user');
INSERT INTO `role` VALUES ('2', 'ROLE_ADMIN', 'user,admin');

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `username` varchar(255) NOT NULL,
  `password` varchar(255) NOT NULL,
  `role_id` int(2) NOT NULL,
  `last_password_change` bigint(13) NOT NULL,
  `enable` tinyint(1) NOT NULL,
  PRIMARY KEY (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('admin', '123456', '2', '0', '1');
INSERT INTO `user` VALUES ('guest', '123456', '1', '0', '1');

userMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.andrewprogramming.springsecuritydemo1.dao.UserMapper">

    <select id="getUserFromDatabase"  resultMap="getUserFromDatabaseMap">
        SELECT
        `user`.username,
        `user`.`password`,
        `user`.role_id,
        `user`.enable,
        `user`.last_password_change,
        `user`.enable,
        role.auth
        FROM
        `user` ,
        role
        WHERE
        `user`.role_id = role.role_id AND
        `user`.username = #{username}
    </select>

    <resultMap id="getUserFromDatabaseMap" type="com.andrewprogramming.springsecuritydemo1.model.User">
        <id column="username" property="username"/>
        <result column="password" property="password"/>
        <result column="last_password_change" property="lastPasswordChange"/>
        <result column="auth" property="authorities"/>
        <result column="enable" property="enable"/>
    </resultMap>

</mapper>

Code

Github

 

 

 

Leave a Reply

Close Menu