Connexion au formulaire Spring Security en utilisant la base de données

Connexion au formulaire Spring Security à l'aide de la base de données

Dans ce didacticiel, nous vous montrerons comment effectuer l'authentification de la base de données (à la fois en XML et en annotations) dans Spring Security.

Technologies utilisées:

  1. Spring 3.2.8.RELEASE

  2. Spring Security 3.2.3.RELEASE

  3. Spring JDBC 3.2.3.RELEASE

  4. Eclipse 4.2

  5. JDK 1.6

  6. Maven 3

  7. Tomcat 6 ou 7 (Servlet 3.x)

  8. MySQL Server 5.6

Leslogin-form in-memory authenticationprécédents seront réutilisés, améliorés pour prendre en charge les fonctionnalités suivantes:

  1. Authentification de base de données, utilisant Spring-JDBC et MySQL.

  2. Sécurité Spring, JSP TagLib,sec:authorize access="hasRole('ROLE_USER')

  3. Personnalisez une page d'accès refusé 403.

1. Démo du projet

2. Répertoire des projets

Passez en revue la structure finale du projet (basée sur XML):

spring-security-database-xml-directory

Passez en revue la structure finale du projet (basée sur les annotations):

spring-security-database-annotation-directory

3. Dépendances du projet

Obtenez la dépendance pour Spring, Spring Security, JDBC, Taglib et MySQL

pom.xml

    
        1.6
        3.2.8.RELEASE
        3.2.3.RELEASE
        1.2
        5.1.30
    

    

        
        
            org.springframework
            spring-core
            ${spring.version}
        

        
            org.springframework
            spring-web
            ${spring.version}
        

        
            org.springframework
            spring-webmvc
            ${spring.version}
        

        
            org.springframework
            spring-jdbc
            ${spring.version}
        

        
        
            org.springframework.security
            spring-security-web
            ${spring.security.version}
        

        
            org.springframework.security
            spring-security-config
            ${spring.security.version}
        

        
        
            org.springframework.security
            spring-security-taglibs
            ${spring.security.version}
        

        
        
            jstl
            jstl
            ${jstl.version}
        

                
        
            mysql
            mysql-connector-java
            ${mysql.connector.version}
        

    

4. Base de données

Pour effectuer l'authentification de la base de données, vous devez créer des tables pour stocker les détails des utilisateurs et des rôles. Veuillez vous référer à ceSpring Security user-schema reference. Voici les scripts MySQL pour créer les tablesusers etuser_roles.

4.1 Create a “users” table.

users.sql

CREATE  TABLE users (
  username VARCHAR(45) NOT NULL ,
  password VARCHAR(45) NOT NULL ,
  enabled TINYINT NOT NULL DEFAULT 1 ,
  PRIMARY KEY (username));

4.2 Create a “user_roles” table.

user_roles.sql

CREATE TABLE user_roles (
  user_role_id int(11) NOT NULL AUTO_INCREMENT,
  username varchar(45) NOT NULL,
  role varchar(45) NOT NULL,
  PRIMARY KEY (user_role_id),
  UNIQUE KEY uni_username_role (role,username),
  KEY fk_username_idx (username),
  CONSTRAINT fk_username FOREIGN KEY (username) REFERENCES users (username));

4.3 Inserts some records for testing.

INSERT INTO users(username,password,enabled)
VALUES ('example','123456', true);
INSERT INTO users(username,password,enabled)
VALUES ('alex','123456', true);

INSERT INTO user_roles (username, role)
VALUES ('example', 'ROLE_USER');
INSERT INTO user_roles (username, role)
VALUES ('example', 'ROLE_ADMIN');
INSERT INTO user_roles (username, role)
VALUES ('alex', 'ROLE_USER');

Note

  1. Nom d'utilisateur «exemple», avec role_user et role_admin.

  2. Nom d'utilisateur «alexa», avec role_user.

5. Configuration de sécurité de printemps

Spring Security en XML et en annotations.

5.1 Create a DataSource to connect MySQL.

spring-database.xml



    

        
        
        
        
    

L'équivalent des annotations de printemps:

SecurityConfig.java

package com.example.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

@EnableWebMvc
@Configuration
@ComponentScan({ "com.example.web.*" })
@Import({ SecurityConfig.class })
public class AppConfig {

    @Bean(name = "dataSource")
    public DriverManagerDataSource dataSource() {
        DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource();
        driverManagerDataSource.setDriverClassName("com.mysql.jdbc.Driver");
        driverManagerDataSource.setUrl("jdbc:mysql://localhost:3306/test");
        driverManagerDataSource.setUsername("root");
        driverManagerDataSource.setPassword("password");
        return driverManagerDataSource;
    }

    @Bean
    public InternalResourceViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setViewClass(JstlView.class);
        viewResolver.setPrefix("/WEB-INF/pages/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }

}

5.2 Use jdbc-user-service to define a query to perform database authentication.

spring-security.xml



    
    

        

        
        

        
        
        
        
    

    
    
      
        
      
    

L'équivalent des annotations Spring Security:

SecurityConfig.java

package com.example.config;

import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    DataSource dataSource;

    @Autowired
    public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {

      auth.jdbcAuthentication().dataSource(dataSource)
        .usersByUsernameQuery(
            "select username,password, enabled from users where username=?")
        .authoritiesByUsernameQuery(
            "select username, role from user_roles where username=?");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

      http.authorizeRequests()
        .antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")
        .and()
          .formLogin().loginPage("/login").failureUrl("/login?error")
          .usernameParameter("username").passwordParameter("password")
        .and()
          .logout().logoutSuccessUrl("/login?logout")
        .and()
          .exceptionHandling().accessDeniedPage("/403")
        .and()
          .csrf();
    }
}

6. Pages JSP

Pages JSP pour une page de connexion personnalisée.

6.1 Default page, show the use of Spring Security JSP taglib sec:authorize to display content to users who have “ROLE_USER” authority.

hello.jsp

<%@taglib prefix="sec"
    uri="http://www.springframework.org/security/tags"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>


    

Title : ${title}

Message : ${message}

User : ${pageContext.request.userPrincipal.name} | Logout

6.2 Page to display the custom login form.

login.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@page session="true"%>


Login Page




    

Spring Security Login Form (Database Authentication)

Login with Username and Password

${error}
${msg}
User:
Password:

6.3 This page is password protected, only authenticated user “ROLE_ADMIN” is allowed to access.

admin.jsp

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@page session="true"%>


    

Title : ${title}

Message : ${message}

Welcome : ${pageContext.request.userPrincipal.name} | Logout

6.4 Custom 403 access denied page.

403.jsp

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>


    

HTTP Status 403 - Access is denied

You do not have permission to access this page!

Username : ${username}
You do not have permission to access this page!

7. Contrôleur Spring MVC

Un contrôleur simple.

MainController.java

package com.example.web.controller;

import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class MainController {

    @RequestMapping(value = { "/", "/welcome**" }, method = RequestMethod.GET)
    public ModelAndView defaultPage() {

      ModelAndView model = new ModelAndView();
      model.addObject("title", "Spring Security Login Form - Database Authentication");
      model.addObject("message", "This is default page!");
      model.setViewName("hello");
      return model;

    }

    @RequestMapping(value = "/admin**", method = RequestMethod.GET)
    public ModelAndView adminPage() {

      ModelAndView model = new ModelAndView();
      model.addObject("title", "Spring Security Login Form - Database Authentication");
      model.addObject("message", "This page is for ROLE_ADMIN only!");
      model.setViewName("admin");
      return model;

    }

    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public ModelAndView login(@RequestParam(value = "error", required = false) String error,
        @RequestParam(value = "logout", required = false) String logout) {

      ModelAndView model = new ModelAndView();
      if (error != null) {
        model.addObject("error", "Invalid username and password!");
      }

      if (logout != null) {
        model.addObject("msg", "You've been logged out successfully.");
      }
      model.setViewName("login");

      return model;

    }

    //for 403 access denied page
    @RequestMapping(value = "/403", method = RequestMethod.GET)
    public ModelAndView accesssDenied() {

      ModelAndView model = new ModelAndView();

      //check if user is login
      Authentication auth = SecurityContextHolder.getContext().getAuthentication();
      if (!(auth instanceof AnonymousAuthenticationToken)) {
        UserDetails userDetail = (UserDetails) auth.getPrincipal();
        model.addObject("username", userDetail.getUsername());
      }

      model.setViewName("403");
      return model;

    }

}

8. Demo

spring-security-database-default

8.2 Try to access /admin page, only “example” ROLE_ADMIN is allowed to access.

spring-security-database-admin

8.3. Si «alex» essaie d'accéder à/admin, la page 403 accès refusé s'affiche.

spring-security-database-403

8.3 “alex” in default page, show the use of sec:authorize

spring-security-database-sec-tag

8.4. Si «exemple» essaie d'accéder à/admin, la page d'administration s'affiche.

spring-security-database-admin-login

Télécharger le code source

Télécharger la version XML -spring-security-login-form-database-xml.zip (16 Ko)

Télécharger la version Annotation -spring-security-login-form-database-annotation.zip (22 Ko)