Set account and password
The first method: configuration file (not commonly used)
application
spring.security.user.name=admin spring.security.user.password=123
The second method: configure the class
Need to inherit WebSecurityConfigurerAdapter
@Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { //Password encryption BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder(); String encode = bCryptPasswordEncoder.encode("456"); //Login authentication auth.inMemoryAuthentication() .withUser("user") .password(encode) .roles("user"); } @Bean public PasswordEncoder password(){ return new BCryptPasswordEncoder(); } }
Overall logic: in the security login, there are only two steps for authentication, which need programmers to do:
1. Get user information
2. Returns user information and permissions.
The rest of the authentication, judgment, etc. are completed internally by security (I don't see much about the source code, so I don't know how to complete it)
realization:
First, I need a class to return user information to security, config
Second, I need a class to get user information, service
config
@Configuration @EnableWebSecurity public class ConfigTest extends WebSecurityConfigurerAdapter{ @Autowired private MyService userDetailsService; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(password()); } @Bean public PasswordEncoder password(){ return new BCryptPasswordEncoder(); } }
Inherit the WebSecurityConfigurerAdapter class and override the configure method. This is an empty method. The specific functions to be implemented here mainly depend on the AuthenticationManagerBuilder in parentheses. This is an authentication manager. Since it is an authentication manager, I need to give it an identity, so I lead to the userDetailsService user details, Now go to the MyService class.
@Service public class MyService implements UserDetailsService{ @Autowired private UserMapper userMapper; @Override public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException{ QueryWrapper<com.tan.pojo.User> wrapper = new QueryWrapper<>(); wrapper.eq("username",s); com.tan.pojo.User user = userMapper.selectOne(wrapper); if(user==null){ throw new UsernameNotFoundException("user name does not exist"); } return new User(user.getUsername(),new BCryptPaswordEncoder().encode(user.getPassword()),auths); //Simulate encryption and return the encrypted password
This is mainly used to obtain the user. You can see the first three lines in the loadUserByUsername method. mybatisPlus is used to find the relevant information of the user in the database and assign it to the user. The next step is to determine whether the user exists. If it does not exist, an exception will be reported directly. If it exists, put the current user into the AuthenticationManagerBuilder through the ConfigTest class above, and the remaining comparison operations are completed by security.
Set authentication
According to the learning needs, set which web sites can be accessed without login and which can be accessed only after login.
Rewrite the http security method in the source code
protected void configure(HttpSecurity http) throws Exception { this.logger.debug("Using default configure(HttpSecurity). If subclassed this will potentially override subclass configure(HttpSecurity)."); http.authorizeRequests((requests) -> { ((AuthorizedUrl)requests.anyRequest()).authenticated(); }); http.formLogin(); http.httpBasic(); }
Rewrite the code according to the current learning needs
@Override protected void configure(HttpSecurity http) throws Exception { http.formLogin() //Enable custom login page .loginPage("/login.html") //Login page setup .loginProcessingUrl("/user/login").permitAll() //Login access path .defaultSuccessUrl("/test/index") //The default success path is the place to jump after success .and().csrf().disable(); //When the csrf function is turned off, security3 is turned off by default and security4 is turned on by default http.authorizeRequests() .antMatchers("/test/index").permitAll()//Give some websites a green light and you can log in without authentication .anyRequest().authenticated(); //All websites need to be certified http.formLogin(); http.httpBasic(); }
There is a problem here. After I rewrite this method, anyrequest () in the original method authenticated(); It is invalid, so when setting the authentication login, add this sentence to the end of the authentication, otherwise an error will be reported
Error creating bean with name 'springSecurityFilterChain' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is java.lang.IllegalStateException: Can't configure antMatchers after anyRequest
As you can see in the last sentence, the nested exception is that ant matchers cannot be configured after anyRequest.
There is also a question I think.. Why can't you turn on the condition that all websites need authentication by default, and then write a method to close it, which makes it clearer..
There are other methods of HttpSecurity in the WebSecurityConfigurerAdapter class:
private void applyDefaultConfiguration(HttpSecurity http) throws Exception { http.csrf(); //The csrf function is enabled by default http.addFilter(new WebAsyncManagerIntegrationFilter()); //filter http.exceptionHandling(); //exception handling http.headers(); //Safety head http.sessionManagement(); //Session manager http.securityContext(); //Store the current user account information and related permissions http.requestCache(); //Request cache http.anonymous(); //anonymous http.servletApi(); //Applet API http.apply(new DefaultLoginPageConfigurer()); //Default login page Configurator http.logout(); //sign out }
3, Set authorization
There are four ways of authorization:
1,hasAuthority
realization:
Set access rights:
List<GrantedAuthority> auths = AuthorityUtils.commaSeparatedStringToAuthorityList("admin");
Set user permissions:
http.authorizeRequests() .antMatchers("/test/hello").hasAnyAuthority("admin")
Disadvantages: only one permission can be added to a user.
2,hasAnyAuthority
The upgraded version of hasAuthority solves the shortcomings of hasAuthority.
realization:
Set access rights:
List<GrantedAuthority> auths = AuthorityUtils.commaSeparatedStringToAuthorityList("admin");
Set user permissions:
http.authorizeRequests() .antMatchers("/test/hello").hasAnyAuthority("admin","user")
3,hasRole
Different from hasAuthority, you need to add a prefix: ROLE when setting access permissions_**
realization:
Set access rights:
List<GrantedAuthority> auths = AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_vvv");
Set user permissions:
http.authorizeRequests() .antMatchers("/test/hello").hasRole("vvv")
It should be noted here that when using hasRole, you cannot set ROLE in user permission_ Nested exceptions will be reported for permissions prefixed with.
4,hasAnyRole
It is equivalent to the combination of hasRole and hasAnyAuthority. A user can have multiple permissions, but it needs to be prefixed with ROLE when setting access permissions_**
realization:
Set access rights:
List<GrantedAuthority> auths = AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_admin");
Set user permissions:
http.authorizeRequests() .antMatchers("/test/hello").hasAnyRole("admin","aaa")