項目:Githubhtml
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.4.1</version> <relativePath/> </parent> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
在manven依賴倉庫中:前端
1.在包下建立SecurityCconfig類,重寫configure方法,其中WebSecurity web,能夠定義忽略路徑java
@Override public void configure(WebSecurity web) throws Exception { //忽略攔截 web.ignoring().antMatchers("/sayHello","/doLogin"); }
@Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests()//開啓登陸 //表示訪問,ex/index 這個接口,須要具有admin角色 .antMatchers("/es/**").hasRole("admin") //表示剩餘的其餘接口,登陸以後能訪問 .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") //登陸處理接口 .loginProcessingUrl("/doLogin") //定義登陸時,用戶名的key,默認爲username .usernameParameter("username") //定義登陸時,用戶密碼的key,默認爲password .passwordParameter("password") //定義登陸成功的處理器 .successHandler(new AuthenticationSuccessHandler() { @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { response.setContentType("application/json;charset=utf-8"); response.sendRedirect("/success.html");//重定向到一個頁面 MyUserDetails detail= (MyUserDetails)authentication.getPrincipal(); System.out.println(detail); } }) .failureHandler(new AuthenticationFailureHandler() { @Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { response.setContentType("application/json;charset=utf-8"); PrintWriter out = response.getWriter(); ResponseBean responseBean = ResponseBean.sendByCode("you have login failure !", 401); String result = new ObjectMapper().writeValueAsString(responseBean); out.write(result); out.flush(); } }) //和表單登陸相關的接口通通都直接經過 .permitAll() .and() .logout() .logoutUrl("/logout") .logoutSuccessHandler(new LogoutSuccessHandler() { @Override public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { response.setContentType("application/json;charset=utf-8"); PrintWriter out = response.getWriter(); out.write("you have login out success !"); out.flush(); } }) .permitAll() .and() .httpBasic() .and() .csrf().disable(); }
簡單的表單登陸配置,這裏的logou是Get請求,若要Post請求,則增長一行
git
logoutRequestMatcher(new AntPathRequestMatcher("/logout","POST"))
and至關於ssm中標籤的結束,permitAll表示登陸相關的頁面、操做不要攔截。github
因爲security自帶鹽,用明文加密的都不同,省去了咱們不少時間。web
@Bean public PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); }
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!-- jpa --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.10</version> </dependency>
@Data @Entity(name = "t_user") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private String username; private String password; private Integer enabled; private Integer locked; }
@Data @Entity(name = "t_role") public class Role { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private String name; private String chineseName; }
@Data public class MyUserDetails implements UserDetails { private User user; private List<Role> roles; @Override public Collection<? extends GrantedAuthority> getAuthorities() { List<SimpleGrantedAuthority> authorities = new ArrayList<>(); if (roles != null && roles.size() > 0) { for (Role role : roles) { authorities.add(new SimpleGrantedAuthority(role.getName())); } } return authorities; } @Override public String getPassword() { return user == null ? null : user.getPassword(); } @Override public String getUsername() { return user == null ? null : user.getUsername(); } @Override public boolean isAccountNonExpired() { return true; } @Override public boolean isAccountNonLocked() { Integer locked = user.getLocked(); if (locked == 0) { return true; } return false; } @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { Integer enabled = user.getEnabled(); if (enabled == 1) { return true; } return false; } @Override public String toString() { return "MyUserDetails{" + "user=" + user + ", roles=" + roles + '}'; } }
在測試類中,建立對象,jpa會自動去建立表格。作一個示範,因爲學習,我先建立的表格,大家能夠少走彎路了。好比下面這樣:
實體,加註解
spring
@Data @Entity(name = "t_hill_heavy") public class HillHeavy { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private String username; private Boolean handsome; private String gender; private Integer high; private boolean rich;
建立Dao
數據庫
public interface HillHeavyDao extends JpaRepository<HillHeavy,Integer> { /** * 查詢 * @param username 用戶名 * @author 山沉 * @date 2020/12/28 22:42 * @return {@link HillHeavy} */ HillHeavy findHillHeavyByUsername(String username); }
在測試類中:
json
@SpringBootTest class EsSearchApplicationTests { private static final Logger logger = LoggerFactory.getLogger(EsSearchApplicationTests.class); @Resource private HillHeavyDao hillHeavyDao; @Test void contextLoads() { HillHeavy hillHeavy = new HillHeavy(); hillHeavy.setUsername("山沉"); hillHeavy.setHandsome(true); hillHeavy.setHigh(180); hillHeavy.setGender("男"); hillHeavy.setRich(true); hillHeavyDao.save(hillHeavy); logger.info("實體----->{}",hillHeavy); } }
這樣在用dao層去注入實體,在數據庫中,也會生成表格,數據。以下:app
是有點自戀,啊。原諒想帥的小胖子。
loadUserByUserName(String username)
在此方法中,從數據庫中根據username,查詢出用戶,角色,返回UserDetail對象。
@Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { User user = userMapper.selectUser(username); MyUserDetails details = new MyUserDetails(); if(user == null){ throw new BadCredentialsException("this username or password is not true!"); } details.setUser(user); Integer id = user.getId(); List<Role> roles = userMapper.selectRole(id); details.setRoles(roles); return details; }
到此,咱們的表單登陸,就成功了。經過doLogin登陸,攜帶user信息,進入UsernamePasswordAuthenticationFilter
中,注入用戶信息。在從表中得到用戶信息與之對比,而後經過登陸成功或失敗返回給前端JSON格式。
在這裏說下,successHandler
是比較強大的,在裏面能夠做重定向,也能夠獲取用戶信息,等等。集成 defaultSuccessUrl() successForwardUrl()
。
defaultSuccessUrl
能夠指定登陸成功的跳轉頁面,好比輸入 welcome/say
,來到login.html
頁面。登陸成功後,會來的welcome/say
。sccessForwardUrl
指定登陸成功後,到那裏。無論登陸前你操做的哪個接口,成功後一概到指定的路徑。測試登陸