Spring Security原始碼分析十六:Spring Security專案實戰
阿新 • • 發佈:2019-01-06
Spring Security是一個能夠為基於Spring的企業應用系統提供宣告式的安全訪問控制解決方案的安全框架。它提供了一組可以在Spring應用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反轉Inversion of Control ,DI:Dependency Injection 依賴注入)和AOP(面向切面程式設計)功能,為應用系統提供宣告式的安全訪問控制功能,減少了為企業系統安全控制編寫大量重複程式碼的工作。
前言
技術棧
- Spring Boot
- Spring Security
- Spring Social(需配置host
127.0.0.1 www.merryyou.cn
- Spring Data JPA
- Freemarker
- Mysql
- Redis
- 前端miniui(非開源)
效果圖
部分程式碼
$.ajax({
url: "${re.contextPath}/connect",
type: "get",
async: true,
dataType: "json",
success: function (data) {
if (data.code === 0 ) {
if (data.data.qq) {
//解綁
$("#bindingQq").attr("title", "解綁")
$(".fa-qq").addClass("social_title");
} else {
//繫結
$("#bindingQq").attr("title" , "繫結")
$(".fa-qq").removeClass("social_title");
}
if (data.data.weixin) {
//解綁
$("#bindingWeixin").attr("title", "解綁")
$(".fa-weixin").addClass("social_title");
} else {
//繫結
$("#bindingWeixin").attr("title", "繫結")
$(".fa-weixin").removeClass("social_title");
}
if (data.data.weibo) {
//解綁
$("#bindingWeibo").attr("title", "解綁")
$(".fa-weibo").addClass("social_title");
} else {
//繫結
$("#bindingWeibo").attr("title", "繫結")
$(".fa-weibo").removeClass("social_title");
}
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(XMLHttpRequest.status);
alert(XMLHttpRequest.readyState);
alert(textStatus); // paser error;
}
});
$.ajax({
url: "${re.contextPath}/role/" + data.id,
cache: false,
success: function (text) {
var o = mini.decode(text);
//設定數的選中狀態
console.log(o.menuIds);
var nodes = tree.getAllChildNodes(tree.getRootNode());
for(var i=0;i<nodes.length;i++){
if(o.menuIds.indexOf(nodes[i]['id'])>=0){
tree.checkNode(nodes[i]);
}else{
tree.uncheckNode(nodes[i]);
}
}
form.setData(o);
form.setChanged(false);
}
});
@Override
public List<MenuDto> getMenusList() {
return repository.findAll().stream()
.map(e ->new MenuDto(e.getId(), e.getPId(), e.getName(), e.getUrl()))
.collect(Collectors.toList());
}
@Override
public Set<String> getUrlByname(String username) {
Set<SysMenu> mesnus = new HashSet<>();
userRepository.findByUsername(username)
.getRoles()
.forEach(e->mesnus.addAll(e.getMenus()));
return mesnus.stream().map(e->e.getUrl()).collect(Collectors.toSet());
}
protected void configure(HttpSecurity http) throws Exception {
// http.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class)
http.headers().frameOptions().disable().and()
.formLogin()//使用表單登入,不再使用預設httpBasic方式
.loginPage(SecurityConstants.DEFAULT_UNAUTHENTICATION_URL)//如果請求的URL需要認證則跳轉的URL
.loginProcessingUrl(SecurityConstants.DEFAULT_SIGN_IN_PROCESSING_URL_FORM)//處理表單中自定義的登入URL
.successHandler(merryyouLoginSuccessHandler)//登入成功處理器,返回JSON
.failureHandler(merryyouAuthenticationfailureHandler)//登入失敗處理器
.and()
.apply(validateCodeSecurityConfig)//驗證碼攔截
.and()
.apply(smsCodeAuthenticationSecurityConfig)
.and()
.apply(merryyouSpringSocialConfigurer)//社交登入
.and()
.rememberMe()
.tokenRepository(persistentTokenRepository())
.tokenValiditySeconds(securityProperties.getRememberMeSeconds())
.userDetailsService(userDetailsService)
.and()
.sessionManagement()
// .invalidSessionStrategy(invalidSessionStrategy)
.invalidSessionUrl("/session/invalid")
.maximumSessions(securityProperties.getSession().getMaximumSessions())//最大session併發數量1
.maxSessionsPreventsLogin(securityProperties.getSession().isMaxSessionsPreventsLogin())//之後的登入踢掉之前的登入
.expiredSessionStrategy(sessionInformationExpiredStrategy)
.and()
.and()
.logout()
.logoutUrl("/signOut")//預設退出地址/logout
.logoutSuccessUrl("/")//退出之後跳轉到註冊頁面
.deleteCookies("JSESSIONID")
.and()
.authorizeRequests().antMatchers(SecurityConstants.DEFAULT_UNAUTHENTICATION_URL,
SecurityConstants.DEFAULT_SIGN_IN_PROCESSING_URL_FORM,
SecurityConstants.DEFAULT_REGISTER_URL,
SecurityConstants.DEFAULT_SIGN_IN_PROCESSING_URL_MOBILE,
SecurityConstants.DEFAULT_SIGN_IN_URL_MOBILE_PAGE,
"/register",
"/socialRegister",//社交賬號註冊和繫結頁面
"/user/register",//處理社交註冊請求
"/social/info",//獲取當前社交使用者資訊
"/session/invalid",
"/**/*.js",
"/**/*.css",
"/**/*.jpg",
"/**/*.png",
"/**/*.woff2",
"/code/*")
.permitAll()//以上的請求都不需要認證
//.antMatchers("/").access("hasRole('USER')")
.and()
.csrf().disable()//關閉csrd攔截
;
//安全模組單獨配置
authorizeConfigProvider.config(http.authorizeRequests());
}
@PreAuthorize("hasAnyAuthority('user:select','user:update')")
@PostMapping(value = "/user/saveUser")
@ResponseBody
public Result saveUser(@RequestParam String data) {
log.info(data);
return sysUserService.save(data);
}
<td style="width:100%;">
<@sec.authorize access="hasAuthority('role:add')">
<a class="mini-button" iconCls="icon-add" onclick="add()">增加</a>
</@sec.authorize>
<@sec.authorize access="hasAuthority('role:update')">
<a class="mini-button" iconCls="icon-add" onclick="edit()">編輯</a>
<@sec.authorize access="hasAuthority('role:del')">
</@sec.authorize>
<a class="mini-button" iconCls="icon-remove" onclick="remove()">刪除</a>
</@sec.authorize>
</td>
啟動方式
- 修改application.yml中資料來源資訊,執行db資料夾下面的sql檔案
- 修改application-dev.yml 中redis連線資訊
- 社交登入需配置host檔案:
127.0.0.1 www.merryyou.cn
微信appid
已過期
程式碼下載
推薦文章
������關注微信小程式java架構師歷程
上下班的路上無聊嗎?還在看小說、新聞嗎?不知道怎樣提高自己的技術嗎?來吧這裡有你需要的java架構文章,1.5w+的java工程師都在看,你還在等什麼?