Get to know spring security

    Authentication and authorization in a system are common things, and now the more popular frameworks are spring security, shiro and so on. They can help us complete the authentication and authorization functions very well. So if we let us complete a login by ourselves, what should the general process be?

 

1. We must have a url processor that processes the form submission on the page. Here we place it in the Filter for processing. If it is called UsernamePasswordAuthenticationFilter   , in this Filter we need to encapsulate the username and password submitted by the user into an object. If it is called UsernamePasswordAuthenticationToken.

2. With the UsernamePasswordAuthenticationToken in the previous step, we must perform an authentication on this token, then there must be an authentication manager ( AuthenticationManager ) in the UsernamePasswordAuthenticationFilter to handle the authentication of our token.

3. With the authentication manager, the authentication manager may be able to handle multiple logins, such as login based on IP address, login based on username and password, login based on remember me ( remember me ) and so on. Then in the implementation of our authentication manager ( ProviderManager ) there should be a set of AuthenticationProviders , each AuthenticationProvider handles different Token authentication.

       For example: DaoAuthenticationProvider is used to handle UsernamePasswordAuthenticationToken

                  RememberMeAuthenticationProvider for handling RememberMeAuthenticationToken

 Fourth , when we are based on user name and password login authentication, then the corresponding AuthenticationProvider is DaoAuthenticationProvider , then we must have an interface to return a user object according to the user name entered by the user, namely UserDetailsService#loadUserByUsername (String) interface, return a UserDetails object, With the user object, the password in our system must be encrypted, so we must also have a password encryptor PasswordEncoder for password verification.

5. After completing the above certification

       Successful authentication : Then there must be a successful callback, and the addition is AuthenticationFailureHandler, in which we can complete the page jump after success

       Authentication failure : There is also a callback for failure. If it is AuthenticationFailureHandler, it can record the failure log and complete the jump after failure.

 

With the above preliminary understanding, let's take a look at how to do it in spring security.

 

1. Introduce the pom configuration file of spring security

<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>io.spring.platform</groupId>
				<artifactId>platform-bom</artifactId>
				<version>Brussels-SR1</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
	</dependencies>

 Second, the configuration of spring security

/**
 * Configuration of spring security
 *
 * @describe
 * @authorhuan
 *@time November 1, 2017 - 9:33:59 pm
 */
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.userDetailsService(createUserDetailService())//
				.passwordEncoder(passwordEncoder())//
				.and()//
				.inMemoryAuthentication()//
				.withUser("admin")
				.password("admin")
				.roles("ADMIN");//Configure a user with username and password
	}
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.formLogin() // form login
				.loginProcessingUrl("/login")// Process login requests
				.loginPage("/login.html") // custom login page
				.usernameParameter("authUsername")//The value of the name of the username of the login form
				.passwordParameter("authPassword")//The value of the name of the login form password
				.successHandler(securityAuthenticationSuccessHandler())// Processing after successful authentication
				.failureHandler(securityAuthenticationFailureHandler()) // Processing after authentication failure
				.and()//
			.userDetailsService(createUserDetailService()) // User service, load user information according to the user name
			.logout() // log out
				.logoutUrl("/logout") // url path to logout
				.addLogoutHandler(securityLogoutHandler())//Processing operations when logging out
				.clearAuthentication(true)// clear authentication
				.invalidateHttpSession(true)// session invalid
				.and()//
			.csrf() // csrf
				.disable()//
			.authorizeRequests()//
				.antMatchers("/login.html","/login").permitAll() // anonymous access
				.anyRequest().authenticated() // Except for the above request, the rest of the requests require authentication before they can be accessed
				.and()//
			.exceptionHandling()//
				.accessDeniedPage("/403.html"); // the page without permission to access
	}

	@Bean
	public AuthenticationFailureHandler securityAuthenticationFailureHandler() {
		SecurityAuthenticationFailureHandler authenticationFailureHandler = new SecurityAuthenticationFailureHandler();
		authenticationFailureHandler.setDefaultFailureUrl("/login.html?error");
		return authenticationFailureHandler;
	}

	@Bean
	public AuthenticationSuccessHandler securityAuthenticationSuccessHandler() {
		SecurityAuthenticationSuccessHandler authenticationSuccessHandler = new SecurityAuthenticationSuccessHandler();
		authenticationSuccessHandler.setAlwaysUseDefaultTargetUrl(true);
		authenticationSuccessHandler.setDefaultTargetUrl("/index.html");
		return authenticationSuccessHandler;
	}

	@Bean
	public LogoutHandler securityLogoutHandler() {
		return new SecurityLogoutHandler();
	}
	
	@Bean
	public UserDetailsService createUserDetailService() {
		return new SecurityUserDetailServiceImpl(passwordEncoder());
	}

	/** Password encryptor */
	@Bean
	public PasswordEncoder passwordEncoder() {
		return new BCryptPasswordEncoder();
	}
}

 3. Each entity class

 4. Login page

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>User login</title>
</head>
<body>
	<form action="/login" method="post">
		Username:<input type="text" name="authUsername" /><br />
		密码:<input type="password" name="authPassword" /><br/>
		<input type="submit" value="登录">
	</form>
</body>
</html>

 5. Home

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Home</title>
<link rel="stylesheet" type="text/css" href="/static/css/index.css">
</head>
<body>
	<h1>
		login successful. <a href="/logout">Logout</a>
	</h1>
</body>
</html>

 6. Interface effect

login page

Home page after successful login

 
 

 

 

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326687298&siteId=291194637