In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/01 Report--
This article mainly explains "how SpringBoot+SpringSecurity handles Ajax login requests". The explanation in the article is simple and clear and easy to learn and understand. Please follow the editor's train of thought to study and learn "how SpringBoot+SpringSecurity handles Ajax login requests".
Problem: the front end is separated from the front end, and the front end is done with Vue, and all data requests use vue-resource instead of forms, so data interaction uses JSON, background uses Spring Boot, and permission verification uses Spring Security, because previously, Spring Security is used to deal with pages, this time only deal with Ajax requests, so record some problems encountered. The solution here is not only suitable for Ajax requests, but also for mobile request authentication.
Create a project
First of all, we need to create a Spring Boot project, which requires the introduction of Web, Spring Security, MySQL and MyBatis (the database framework is actually arbitrary. I use MyBatis here). After creating it, the dependent files are as follows:
Org.mybatis.spring.boot mybatis-spring-boot-starter 1.3.1 org.springframework.boot spring-boot-starter-security org.springframework.boot spring-boot-starter-web mysql mysql-connector-java runtime commons-codec commons-codec 1.11
Note that I manually added the last commons-codec dependency, which is an open source project for Apache that can be used to generate MD5 message digests. I will simply deal with passwords later.
Create the database and configure
To simplify the logic, I have created three tables here, namely, the user table, the role table, and the user role association table, as follows:
Next, we need to make a simple configuration of our database in application.properties, where the partners depend on their own specific circumstances.
Spring.datasource.url=jdbc:mysql:///vueblogspring.datasource.username=rootspring.datasource.password=123 constructs entity classes
This mainly refers to the construction of user classes. The user classes here are special and must implement the UserDetails interface, as shown below:
Public class User implements UserDetails {private Long id; private String username; private String password; private String nickname; private boolean enabled; private List roles; @ Override public boolean isAccountNonExpired () {return true;} @ Override public boolean isAccountNonLocked () {return true;} @ Override public boolean isCredentialsNonExpired () {return true;} @ Override public boolean isEnabled () {return enabled } @ Override public List getAuthorities () {List authorities = new ArrayList (); for (Role role: roles) {authorities.add ("ROLE_" + role.getName ());} return authorities;} / / getter/setter omitted.}
After implementing the UserDetails interface, there are several methods in this interface that we need to implement. The four methods that return Boolean are all known by name. Enabled indicates whether the term account is enabled or not. This field does exist in my database, so it is returned according to the query result. Other methods directly return the current user's role information for a simple period. The user's role is actually the data in roles. After converting the data in roles to List, you can return it. Here is one thing to note. Since the role names I store in the database are all 'Super Admin' and 'ordinary user', they do not start with characters such as ROLE_, so I need to manually add ROLE_, here.
There is also a Role entity class, which is relatively simple and can be created according to the fields of the database. I will not repeat it here.
Create UserService
The UserService here is also special. You need to implement the UserDetailsService API, as follows:
@ Servicepublic class UserService implements UserDetailsService {@ Autowired UserMapper userMapper; @ Autowired RolesMapper rolesMapper; @ Override public UserDetails loadUserByUsername (String s) throws UsernameNotFoundException {User user = userMapper.loadUserByUsername (s); if (user = = null) {/ / avoid returning null, which returns a User object that does not contain any value, and will also fail to verify return new User () in the later password comparison process. } / / query the role information of the user and return List roles = rolesMapper.getRolesByUid (user.getId ()); user.setRoles (roles); return user;}} stored in user
After implementing the UserDetailsService interface, we need to implement the loadUserByUsername method in the interface, that is, query the user by user name. Here we inject two Mapper,UserMapper in MyBatis to query the user and RolesMapper to query the role. In the loadUserByUsername method, first query the user according to the passed parameter (the parameter is the user name entered when the user logs in). If the user is null, you can throw a UsernameNotFoundException exception directly, but for convenience, I returned a User object without any value, so you will also find login failure in the later password comparison process (here, you can adjust according to your business needs) If the user found is not null, we will query the user's role based on the user id and put the query result into the user object. The query result will be used in the getAuthorities method of the user object.
Security configuration
Let's first take a look at my Security configuration, and then I'll explain them one by one:
@ Configurationpublic class WebSecurityConfig extends WebSecurityConfigurerAdapter {@ Autowired UserService userService; @ Override protected void configure (AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService (userService) .passwordEncoder (new PasswordEncoder () {@ Override public String encode (CharSequence charSequence) {return DigestUtils.md5DigestAsHex (charSequence.toString (). GetBytes () } / * * @ param charSequence plaintext * @ param s ciphertext * @ return * / @ Override public boolean matches (CharSequence charSequence, String s) {return s.equals (DigestUtils.md5DigestAsHex (charSequence.toString (). GetBytes ());}}) } @ Override protected void configure (HttpSecurity http) throws Exception {http.authorizeRequests () .antMatrices ("/ admin/**"). HasRole ("Super Admin") .anyRequest () .authenticated () / other paths can be accessed after login. And (). FormLogin (). LoginPage ("/ login_page") .roomHandler (new AuthenticationSuccessHandler) () {@ Override public void onAuthenticationSuccess (HttpServletRequest httpServletRequest HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {httpServletResponse.setContentType ("application/json Charset=utf-8 "); PrintWriter out = httpServletResponse.getWriter (); out.write (" {\ "status\":\ "ok\",\ "msg\":\ "login succeeded\"} "); out.flush (); out.close ();}) .failureHandler (new AuthenticationFailureHandler ()) {
@ Override
Public void onAuthenticationFailure (HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
HttpServletResponse.setContentType ("application/json;charset=utf-8")
PrintWriter out = httpServletResponse.getWriter ()
Out.write ("{\" status\ ":\" error\ ",\" msg\ ":\" login failed\ ")
Out.flush ()
Out.close ()
}
}) .loginProcessingUrl ("/ login") .usernameParameter ("username"). PasswordParameter ("password"). PermitAll () and (). Logout (). PermitAll (). And (). Csrf (). Disable (); @ Override public void configure (WebSecurity web) throws Exception {web.ignoring (). AntMatchers ("/ reg");}}
This is the core of our configuration, friends, listen to me one by one:
1. First of all, this is a configuration class, so remember to add the @ Configuration annotation, and because this is the configuration of Spring Security, remember to inherit WebSecurityConfigurerAdapter.
two。 Inject the UserService you just created, and we'll use it later.
The 3.configure (AuthenticationManagerBuilder auth) method is used to configure our authentication method by passing userService in the auth.userDetailsService () method so that the loadUserByUsername method in userService will be called automatically when the user logs in. The following passwordEncoder is optional, but can be written but not written, because I generate the MD5 message summary of the user's plaintext password and store it in the database, so I also need to deal with the plaintext password when logging in, so I added passwordEncoder, plus passwordEncoder, directly new a PasswordEncoder anonymous inner class, here there are two methods to implement, see the name to know the meaning of the method, the first method encode is obviously to encrypt the plaintext Here I use the MD5 message digest, which is provided by the commons-codec dependency The second method matches is the password comparison, two parameters, the first parameter is the plaintext password, the second is the ciphertext, here only need to encrypt the plaintext and ciphertext comparison (if you are interested in this, you can continue to consider the password salt).
4.configure (HttpSecurity http) is used to configure our authentication rules. AuthorizeRequests method means that authentication rule configuration is enabled. AntMatchers ("/ admin/**"). HasRole ("Super Admin") indicates that the path of / admin/** can only be accessed by users with the role of "Super Admin". I saw on the Internet that a partner has questions about whether to add a ROLE_ prefix to the hasRole method. Do not add it here, but only if you use the hasAuthority method. AnyRequest (). Authenticated () indicates that all other paths require authentication / login before they can be accessed. Next, we configure the login page as login_page, login processing path as / login, login user name as username, password as password, and configure these paths to be accessible directly, logout login can also be accessed directly, and finally close csrf. In successHandler, you can use response to return the json of a successful login. Keep in mind that defaultSuccessUrl,defaultSuccessUrl is only a page that is redirected after a successful login, and failureHandler is used for the same reason.
I have configured some filtering rules in the 5.configure (WebSecurity web) method, which I will not repeat.
6. In addition, static files, such as / images/**, / css/**, / js/**, are not intercepted by default.
Controller
Finally, let's take a look at our Controller, as follows:
@ RestControllerpublic class LoginRegController {/ * if you automatically jump to this page, indicating that the user is not logged in, you can return the appropriate prompt *
* if you want to support form login, you can determine the type of request in this method, and then decide whether to return JSON or HTML page * * @ return * / @ RequestMapping ("/ login_page") public RespBean loginPage () {return new RespBean ("error", "login!");}}
On the whole, this Controller is relatively simple. RespBean a response bean and return a simple json. What we need to pay attention to here is login_page. The login page we configured is a login_page, but in fact, login_page is not a page, but returns a JSON. This is because when I visit another page without logging in, Spring Security will automatically jump to the login_page page, but in the Ajax request I don't need this jump, all I want is a hint of whether to log in, so just return json here.
Thank you for your reading, the above is the content of "how SpringBoot+SpringSecurity handles Ajax login requests". After the study of this article, I believe you have a deeper understanding of how SpringBoot+SpringSecurity handles Ajax login requests, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.