如何在使用Spring Security的安全REST端点下插入数据到MYSQL数据库中。

huangapple 未分类评论48阅读模式
英文:

How to insert data under secure rest endpoints by spring security using MYSQL

问题

我是 Spring Boot 2 的新手。我正在按照这篇 [文章][1] 创建使用 Spring Security 和基于 MySQL 的身份验证的 RESTful 服务,但在注册过程中遇到了问题。

**问题 1**:我无法理解注册具有特定角色的用户的 URL 请求模式。
**问题 2**:在浏览器端,如果我访问 `localhost:8080`,我会得到一个登录页面,但我还没有实现这个页面。为什么我会得到一个 UI,以及它是从哪里来的?

Pom.xml

    <!-- Pom.xml 部分省略 -->

[这是登录界面,对我来说现在是个奇迹。][2]

Auth 控制器(REST 控制器)

    @RequestMapping(value = "/registration", method = RequestMethod.POST)
    public ResponseEntity<Users> createNewUser(@Valid Users user, String role) {
        
        Users userExists = userService.findUserByEmail(user.getEmail());
        if (userExists == null) {
            ResponseEntity.badRequest().build();
        } 
        return ResponseEntity.ok(userService.save(user, role));
    }

WebSecurityConfigurerAdapter 子类文件

    // WebSecurityConfigurerAdapter 部分省略

User 实体类

    // User 实体类部分省略

Service 类

    // Service 类部分省略

MyUserDetailsService 类

    // MyUserDetailsService 类部分省略

MyUserDetails 类

    // MyUserDetails 类部分省略

我认为我已经完成了所有步骤。不知道如何保存/注册新用户。如果能够成功注册用户,我就可以测试我的登录 URL 了。提前感谢您的帮助。

[1]: https://medium.com/@gustavo.ponce.ch/spring-boot-spring-mvc-spring-security-mysql-a5d8545d837d
[2]: https://i.stack.imgur.com/sUNpz.png
英文:

I am new to spring boot 2. For creating rest-full service using spring security and MySQL based authentication, I am following this article but got stucked in registration process.

Problem 1: I am unable to understand URL requesting pattern to register a user with particular role.
Problem 2: On browser side, If I hit localhost:8080 then I get login page which I haven't implemented. Why I am getting a UI and from where?

Pom.xml

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd&quot;&gt;
	&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
	&lt;parent&gt;
		&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
		&lt;artifactId&gt;spring-boot-starter-parent&lt;/artifactId&gt;
		&lt;version&gt;2.2.5.RELEASE&lt;/version&gt;
		&lt;relativePath/&gt; &lt;!-- lookup parent from repository --&gt;
	&lt;/parent&gt;
	&lt;groupId&gt;badar.tme&lt;/groupId&gt;
	&lt;artifactId&gt;tme&lt;/artifactId&gt;
	&lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;
	&lt;packaging&gt;war&lt;/packaging&gt;
	&lt;name&gt;tme&lt;/name&gt;
	&lt;description&gt;TME ordering system developed by ONSETS&lt;/description&gt;

	&lt;properties&gt;
		&lt;java.version&gt;1.8&lt;/java.version&gt;
	&lt;/properties&gt;

	&lt;dependencies&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
			&lt;artifactId&gt;spring-boot-starter-data-jpa&lt;/artifactId&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
			&lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
		&lt;/dependency&gt;

		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
			&lt;artifactId&gt;spring-boot-devtools&lt;/artifactId&gt;
			&lt;scope&gt;runtime&lt;/scope&gt;
			&lt;optional&gt;true&lt;/optional&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;mysql&lt;/groupId&gt;
			&lt;artifactId&gt;mysql-connector-java&lt;/artifactId&gt;
			&lt;scope&gt;runtime&lt;/scope&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.projectlombok&lt;/groupId&gt;
			&lt;artifactId&gt;lombok&lt;/artifactId&gt;
			&lt;optional&gt;true&lt;/optional&gt;
		&lt;/dependency&gt;
		&lt;!-- spring security --&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
            &lt;artifactId&gt;spring-boot-starter-security&lt;/artifactId&gt;
        &lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
			&lt;artifactId&gt;spring-boot-starter-tomcat&lt;/artifactId&gt;
			&lt;scope&gt;provided&lt;/scope&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
			&lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt;
			&lt;scope&gt;test&lt;/scope&gt;
			&lt;exclusions&gt;
				&lt;exclusion&gt;
					&lt;groupId&gt;org.junit.vintage&lt;/groupId&gt;
					&lt;artifactId&gt;junit-vintage-engine&lt;/artifactId&gt;
				&lt;/exclusion&gt;
			&lt;/exclusions&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework.security&lt;/groupId&gt;
			&lt;artifactId&gt;spring-security-test&lt;/artifactId&gt;
			&lt;scope&gt;test&lt;/scope&gt;
		&lt;/dependency&gt;
	&lt;/dependencies&gt;

	&lt;build&gt;
		&lt;plugins&gt;
			&lt;plugin&gt;
				&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
				&lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt;
			&lt;/plugin&gt;
		&lt;/plugins&gt;
	&lt;/build&gt;

&lt;/project&gt;

Here is Login UI which is miracle for me right now.

Auth Controller (rest controller)

 @RequestMapping(value = &quot;/registration&quot;, method = RequestMethod.POST)
	    public ResponseEntity&lt;Users&gt; createNewUser(@Valid Users user, String role) {
	        
	        Users userExists = userService.findUserByEmail(user.getEmail());
	        if (userExists == null) {
	        	ResponseEntity.badRequest().build();
	        } 
	        return ResponseEntity.ok(userService.save(user, role));
	    }

WebSecurityConfigurerAdapter child file

package com.tme.runner;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

import com.tme.service.MyUserDetailsService;

@EnableGlobalMethodSecurity(prePostEnabled = true)
@Configuration
@EnableWebSecurity
@EnableJpaRepositories(basePackageClasses = com.tme.repo.UserRepository.class)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter{

	@Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

	@Bean
    public BCryptPasswordEncoder passwordEncoder() {
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        return bCryptPasswordEncoder;
    }
	
    @Autowired
    private MyUserDetailsService userDetailsService;
    
//    @Bean
//    public PasswordEncoder passwordEncoder() {
//        return new BCryptPasswordEncoder();
//    }


    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
                auth
                    .userDetailsService(userDetailsService)
                    .passwordEncoder(bCryptPasswordEncoder);
    }
    
    
   
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
        		.httpBasic()
        		.and()
        		.authorizeRequests()
                .antMatchers(&quot;/login&quot;).permitAll()
                .antMatchers(&quot;/registration&quot;).permitAll()
                .antMatchers(&quot;/api/v1/**&quot;).hasAuthority(&quot;ADMIN&quot;)
                .and()
                .csrf().disable()
                .formLogin().disable();
                
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web
                .ignoring()
                .antMatchers(&quot;/resources/**&quot;, &quot;/static/**&quot;, &quot;/css/**&quot;, &quot;/js/**&quot;, &quot;/images/**&quot;);
    }
    
}

User Entity class

package com.tme.model;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.validator.constraints.Length;
import javax.persistence.*;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
import java.util.Set;


/**
 * @author badar
 */
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = &quot;users&quot;)
public class Users {

	@Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = &quot;user_id&quot;)
    private int id;
    @Column(name = &quot;user_name&quot;)
    @Length(min = 5, message = &quot;*Your user name must have at least 5 characters&quot;)
    @NotEmpty(message = &quot;*Please provide a user name&quot;)
    private String userName;
    @Column(name = &quot;email&quot;)
    @Email(message = &quot;*Please provide a valid Email&quot;)
    @NotEmpty(message = &quot;*Please provide an email&quot;)
    private String email;
    @Column(name = &quot;password&quot;)
    @Length(min = 5, message = &quot;*Your password must have at least 5 characters&quot;)
    @NotEmpty(message = &quot;*Please provide your password&quot;)
    private String password;
    @Column(name = &quot;name&quot;)
    @NotEmpty(message = &quot;*Please provide your name&quot;)
    private String name;
    @Column(name = &quot;last_name&quot;)
    @NotEmpty(message = &quot;*Please provide your last name&quot;)
    private String lastName;
    @Column(name = &quot;active&quot;)
    private Boolean active;
    @ManyToMany(cascade = CascadeType.MERGE)
    @JoinTable(name = &quot;user_role&quot;, joinColumns = @JoinColumn(name = &quot;user_id&quot;), inverseJoinColumns = @JoinColumn(name = &quot;role_id&quot;))
    private Set&lt;Roles&gt; roles;
    
    public Users() {}
    public Users(
			String userName,
			String email,
			String password,
			String name,
			String lastName, 
			Boolean active) {
		
		this.userName = userName;
		this.email = email;
		this.password = password;
		this.name = name;
		this.lastName = lastName;
		this.active = active;
	}
	public Users(
			String userName,
			String email,
			String password,
			String name,
			String lastName, 
			Boolean active, 
			Set&lt;Roles&gt; roles) {
		
		this.userName = userName;
		this.email = email;
		this.password = password;
		this.name = name;
		this.lastName = lastName;
		this.active = active;
		this.roles = roles;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public Boolean getActive() {
		return active;
	}

	public void setActive(Boolean active) {
		this.active = active;
	}

	public Set&lt;Roles&gt; getRoles() {
		return roles;
	}

	public void setRoles(Set&lt;Roles&gt; roles) {
		this.roles = roles;
	}
    
    
    
}

Service Class

package com.tme.service;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import com.tme.model.Roles;
import com.tme.model.Users;
import com.tme.repo.RoleRepository;
import com.tme.repo.UserRepository;

@Service
public class UsersServices {

	@Autowired(required=false)
	private UserRepository userRepository;
	@Autowired(required=false)
    private RoleRepository roleRepository;
    @Autowired(required=false)
    private BCryptPasswordEncoder bCryptPasswordEncoder;

//    public UsersServices(BCryptPasswordEncoder bCryptPasswordEncoder,UserRepository userRepository,
//                       RoleRepository roleRepository
//                       ) {
//        this.userRepository = userRepository;
//        this.roleRepository = roleRepository;
//        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
//    }
    
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
	
	public List&lt;Users&gt; findAll(){
		return userRepository.findAll();
	}
	
	public Users findUserByEmail(String email) {
        return userRepository.findByEmail(email);
    }
	
	public Users findUserByUserName(String userName) {
        return userRepository.findByUserName(userName);
    }
	
	public Optional&lt;Users&gt; findById(Long id){
		return userRepository.findById(id);
	}
	
	public Users save(Users data) {
		data.setPassword(bCryptPasswordEncoder.encode(data.getPassword()));
		data.setActive(true);
        Roles userRole = roleRepository.findByRole(&quot;ADMIN&quot;);
        data.setRoles(new HashSet&lt;Roles&gt;(Arrays.asList(userRole)));
        return userRepository.save(data);
	}
	
	public Users save(Users data, String role) {
		data.setPassword(bCryptPasswordEncoder.encode(data.getPassword()));
        Roles userRole = roleRepository.findByRole(role);
        data.setRoles(new HashSet&lt;Roles&gt;(Arrays.asList(userRole)));
        return userRepository.save(data);
	}
	
	public void deleteById(Long id) {
		userRepository.deleteById(id);
	}
}

MyUserDetailsService class

@Service
public class MyUserDetailsService implements UserDetailsService{

	@Autowired
    private UsersServices userService;
    
    @Override
    @Transactional
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
    	
        Users user = userService.findUserByEmail(email);
        if (user == null) {
            throw new UsernameNotFoundException(&quot;Not found!&quot;);
        }
        
        List&lt;GrantedAuthority&gt; authorities = getUserAuthority(user.getRoles());
        return buildUserForAuthentication(user, authorities);
    }

    private List&lt;GrantedAuthority&gt; getUserAuthority(Set&lt;Roles&gt; userRoles) {
        Set&lt;GrantedAuthority&gt; roles = new HashSet&lt;GrantedAuthority&gt;();
        for (Roles role : userRoles) {
            roles.add(new SimpleGrantedAuthority(role.getRole()));
        }
        List&lt;GrantedAuthority&gt; grantedAuthorities = new ArrayList&lt;&gt;(roles);
        return grantedAuthorities;
    }
    
    private UserDetails buildUserForAuthentication(Users user, List&lt;GrantedAuthority&gt; authorities) {
        return new org.springframework.security.core.userdetails.User(user.getUserName(), user.getPassword(),
                user.getActive(), true, true, true, authorities);
    }
}

MyUserDetail

public class MyUserDetails extends Users implements UserDetails{
	
	private String userName;
	private String email;
	private String password;
	private String name;
	private String lastName; 
	private Boolean active;
	 
	
	public MyUserDetails(Users user) {
		this.userName = user.getUserName();
		this.email = user.getEmail();
		this.password = user.getPassword();
		this.name = user.getName();
		this.lastName = user.getLastName();
		this.active = user.getActive();
	}
	
	
	
	@Override
	public Collection&lt;? extends GrantedAuthority&gt; getAuthorities() {
		// TODO Auto-generated method stub
		return getRoles()
                .stream()
                .map(role -&gt; new SimpleGrantedAuthority(&quot;ROLE_&quot; + role.getRole()))
                .collect(Collectors.toList());
	}

	@Override
	public String getPassword() {
		// TODO Auto-generated method stub
		return password;
	}

	@Override
	public String getUsername() {
		// TODO Auto-generated method stub
		return userName;
	}

	@Override
	public boolean isAccountNonExpired() {
		// TODO Auto-generated method stub
		return true;
	}

	@Override
	public boolean isAccountNonLocked() {
		// TODO Auto-generated method stub
		return true;
	}

	@Override
	public boolean isCredentialsNonExpired() {
		// TODO Auto-generated method stub
		return true;
	}

	@Override
	public boolean isEnabled() {
		// TODO Auto-generated method stub
		return active;
	}

}

I think I have done every thing. Don't know how to save/Regsiter New user. If I will be able to regsiter a user then can test my login URL. Thanks inadvance.

答案1

得分: 0

请将以下行添加到您的application.properties文件中:

management.security.enabled= false
英文:

Please add this line in your application.properties file

management.security.enabled= false

huangapple
  • 本文由 发表于 2020年4月6日 10:19:22
  • 转载请务必保留本文链接:https://java.coder-hub.com/61052063.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定