springboot整合springsecurity遇到的問題

來源:互聯網
上載者:User

標籤:資訊   handler   val   注意   null   lin   out   源碼   功能   

在整合springsecurity時遇到好幾個問題,自動設定登入,下線,登出使用者的操作,資料基於mybatis,模版引擎用的thymeleaf+bootstrap。

 一、認證時密碼的加密(passwordEncoder)原理如下

  •      其中 MD5Util是自訂密碼加密工具類,隨便寫(注意添加鹽值),注意點:理解匹配密碼這個過程
//認證    @Override    protected void configure(AuthenticationManagerBuilder auth)            throws Exception {        auth.userDetailsService(userDetailsService()).passwordEncoder(new  PasswordEncoder() {            @Override            public boolean matches(CharSequence rawPassword, String encodedPassword) {                //匹配   =================將使用者表單登入的密碼和encodedPasswor(這個值是從MyUserDetailService那邊封裝過來的))對比=================                return encodedPassword.equals(encode(rawPassword));            }            @Override            public String encode(CharSequence rawPassword) {                return MD5Util.encode((String) rawPassword);            }        });            }
  • MyUserDetailService是一個實現了UserDetailsService(springsecurity本身的介面)的方法,在這裡面實現認證的資料查詢及其登入使用者權限查詢封裝。
  • 注意點:理解許可權的賦予,即目前使用者在這裡就已經將所有的角色封裝到springsecurity本身的User中了,但是在這裡並沒有認證成功,單純的進行封裝而已
@Servicepublic class MyUserDetailService implements UserDetailsService {    @Autowired    UserService userService;    @Autowired    private SessionRegistry sessionRegistry;        @Override    public UserDetails loadUserByUsername(String username)  {                if (username==null || username.equals("")) {             throw new UsernameNotFoundException("使用者名稱不存在");        }                Sys_User user=userService.getUserByName(username);                 //獲得所有登入使用者的資訊         List<Object> list =sessionRegistry.getAllPrincipals();         for (Object object : list) {             if (((User)object).getUsername().equals(user.getUsername())) {                 throw new SessionAuthenticationException("目前使用者已經線上,登入失敗");             }             System.out.println("getAllPrincipals的遍曆"+((User)object).getUsername());         }                //得到當前登入使用者的資訊         List<SimpleGrantedAuthority> authorities = new ArrayList<>();                  for (Role role : user.getRoles()) {             //將得到的角色封裝  在後面頁面認證成功後會用到               authorities.add(new SimpleGrantedAuthority(role.getRolename()));               System.out.println("擁有的角色:"+role.getRolename());            }        return  new User(user.getUsername(), user.getPassword(), authorities);    }}
View Code

二、授權時session的管理的配置(configure(HttpSecurity http)中)

  •  這個可以說是核心了,首先開啟自動設定的登出功能(重點在開啟否則預設的是內建的登出頁面),LogoutUrl:自訂的登出URL,登出成功後的頁面也可以自訂,這裡就都不寫了,在controller層實現自己定義的
//開啟自動設定的登出功能。        http.logout().permitAll();//logoutUrl("/logout").logoutSuccessUrl("/");//表示登出成功以後來到首頁        http //session管理        .sessionManagement()        .maximumSessions(1).maxSessionsPreventsLogin(true)        .sessionRegistry(getSessionRegistry());
  • http.sessionManagement().invalidSessionUrl("/login") 使用未到期但完全無效的sessionid使用者發送請求,也會被重新導向至特定url
 http.sessionManagement().maximumSessions(1).maxSessionsPreventsLogin(true)
  • MaximumLogins必須是-1以允許無限制的登入,或者是一個正整數來指定最大值
  • .maximumSessions(1)設定一個使用者允許登入的個數    maxSessionsPreventsLogin 啟用超出報錯。

    在實測後發現設定上限後 最大登入次數為設定數目 +1 比如設定數2 則最大訪問數目為3 第四次開始報錯
    由此 如果我們用這個配置去指定使用者單登入是不行的

  • http.sessionManagement().sessionFixation().migrateSession()spring security防止篡改session

三、自訂登出,下線的實現(重點)

  • 第一種實現單純的進行了下線,暫時將session置為無效,並未去掉(看源碼部分)
if (invalidateHttpSession) {//部分源碼            HttpSession session = request.getSession(false);            if (session != null) {                logger.debug("Invalidating session: " + session.getId());                session.invalidate();            }        }

 

 @RequestMapping("/logout")    public String logout(HttpServletRequest request,HttpServletResponse response){        /**         * 第一種方式  單純的離線  並未登出使用者   即sessionID還在         *          */                //獲得登出使用者的資訊        Authentication auth=SecurityContextHolder.getContext().getAuthentication();        if (auth != null){            //設定為離線狀態           new SecurityContextLogoutHandler().logout(request, response, auth);        }        return "redirect:/login";            }
  • 第二種徹底將sessionid從sessionRegistry中移除,實現使用者登出
@RequestMapping("/logout")    public  String  logout2() {                  /**         * 第二種  將擷取到登入使用者資訊後將該使用者sessionID置為無效   然後再從sessionRegistry中移除         * 這種方式可以徹底登出使用者登入狀態         */            List<Object> pList=sessionRegistry.getAllPrincipals();    List<SessionInformation>  sessionsInfo = null;    for (Object principle : pList) {        sessionsInfo=sessionRegistry.getAllSessions(principle, false);    }         System.out.println("sesssion個數"+sessionsInfo.size());         for (SessionInformation sessionInformation : sessionsInfo) {             //擷取當前sessionid             System.out.println("SESSIONID:"+sessionInformation.getSessionId());             sessionInformation.expireNow();//將session置為無效然後在下一步移除             sessionRegistry.removeSessionInformation(sessionInformation.getSessionId());        }        return "redirect:/login";    }    

四、源碼

源碼實現私信我

 

springboot整合springsecurity遇到的問題

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.