<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.0</version> </dependency>
##端口號 server.port=8888 ##數據庫配置 ##數據庫地址 spring.datasource.url=jdbc:mysql://localhost:3306/shiro?characterEncoding=utf8&useSSL=false\ &serverTimezone=GMT%2B8 ##數據庫用戶名 spring.datasource.username=root ##數據庫密碼 spring.datasource.password=Panbing936@ ##數據庫驅動 spring.datasource.driver-class-name=com.mysql.jdbc.Driver ##validate 加載hibernate時,驗證建立數據庫表結構 ##create 每次加載hibernate,從新建立數據庫表結構,這就是致使數據庫表數據丟失的緣由。 ##create-drop 加載hibernate時建立,退出是刪除表結構 ##update 加載hibernate自動更新數據庫結構 ##validate 啓動時驗證表的結構,不會建立表 ##none 啓動時不作任何操做 spring.jpa.hibernate.ddl-auto=update ##控制檯打印sql spring.jpa.show-sql=true # 建議在開發時關閉緩存,否則無法看到實時頁面 spring.thymeleaf.cache=false ##去除thymeleaf的html嚴格校驗 spring.thymeleaf.mode=LEGACYHTML5 #沒下面這行配置就會報這個錯誤 #Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
@Entity @Data public class SysMenu implements Serializable { @Id @GeneratedValue private Integer menuId; private String menuName; @ManyToMany @JoinTable(name = "SysRoleMenu", joinColumns = {@JoinColumn(name = "menuId")}, inverseJoinColumns = {@JoinColumn(name = "roleId")}) private List<SysRole> roleList; }
@Entity @Data public class SysRole implements Serializable { @Id @GeneratedValue private Integer roleId; private String roleName; //多對多關係 @ManyToMany(fetch = FetchType.EAGER) @JoinTable(name = "SysRoleMenu", joinColumns = {@JoinColumn(name = "roleId")}, inverseJoinColumns = {@JoinColumn(name = "menuId")}) private List<SysMenu> menuList; //多對多關係 @ManyToMany @JoinTable(name = "SysUserRole", joinColumns = {@JoinColumn(name = "roleId")}, inverseJoinColumns = {@JoinColumn(name = "userId")}) private List<SysUser> userList;// 一個角色對應多個用戶 }
@Entity @Data public class SysUser implements Serializable { @Id @GeneratedValue private Integer userId; @NotEmpty private String userName; @NotEmpty private String passWord; //多對多關係 @ManyToMany(fetch = FetchType.EAGER) //急加載,加載一個實體時,定義急加載的屬性會當即從數據庫中加載 //FetchType.LAZY:懶加載,加載一個實體時,定義懶加載的屬性不會立刻從數據庫中加載 @JoinTable(name = "SysUserRole", joinColumns = {@JoinColumn(name = "userId")}, inverseJoinColumns = {@JoinColumn(name = "roleId")}) private List<SysRole> roleList;// 一個用戶具備多個角色 }
public interface UserRepository extends CrudRepository<SysUser,Long> { SysUser findByUserName(String username); }
public class MyShiroRealm extends AuthorizingRealm { @Resource private UserRepository userRepository; //受權 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); SysUser userInfo = (SysUser)principals.getPrimaryPrincipal(); for(SysRole role:userInfo.getRoleList()){ authorizationInfo.addRole(role.getRoleName()); for(SysMenu menu:role.getMenuList()){ authorizationInfo.addStringPermission(menu.getMenuName()); } } return authorizationInfo; } //認證 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { //得到當前用戶的用戶名 String username = (String)token.getPrincipal(); System.out.println(token.getCredentials()); //根據用戶名找到對象 //實際項目中,這裏能夠根據實際狀況作緩存,若是不作,Shiro本身也是有時間間隔機制,2分鐘內不會重複執行該方法 SysUser userInfo = userRepository.findByUserName(username); if(userInfo == null){ return null; } //這裏會去校驗密碼是否正確 SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo( userInfo, //用戶名 userInfo.getPassWord(),//密碼 getName() ); return authenticationInfo; } }
@Configuration public class ShiroConfig { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Bean public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) { logger.info("啓動shiroFilter--時間是:" + new Date()); ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); //shiro攔截器 Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>(); //<!-- authc:全部url都必須認證經過才能夠訪問; anon:全部url都均可以匿名訪問--> //<!-- 過濾鏈定義,從上向下順序執行,通常將/**放在最爲下邊 --> // 配置不被攔截的資源及連接 filterChainDefinitionMap.put("/static/**", "anon"); // 退出過濾器 filterChainDefinitionMap.put("/logout", "logout"); //配置須要認證權限的 filterChainDefinitionMap.put("/**", "authc"); // 若是不設置默認會自動尋找Web工程根目錄下的"/login"頁面,即本文使用的login.html shiroFilterFactoryBean.setLoginUrl("/login"); // 登陸成功後要跳轉的連接 shiroFilterFactoryBean.setSuccessUrl("/index"); //未受權界面 shiroFilterFactoryBean.setUnauthorizedUrl("/403"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; } //自定義身份認證Realm(包含用戶名密碼校驗,權限校驗等) @Bean public MyShiroRealm myShiroRealm(){ MyShiroRealm myShiroRealm = new MyShiroRealm(); return myShiroRealm; } @Bean public SecurityManager securityManager(){ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(myShiroRealm()); return securityManager; } //開啓shiro aop註解支持,不開啓的話權限驗證就會失效 @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){ AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); return authorizationAttributeSourceAdvisor; } //配置異常處理,不配置的話沒有權限後臺報錯,前臺不會跳轉到403頁面 @Bean(name="simpleMappingExceptionResolver") public SimpleMappingExceptionResolver createSimpleMappingExceptionResolver() { SimpleMappingExceptionResolver simpleMappingExceptionResolver = new SimpleMappingExceptionResolver(); Properties mappings = new Properties(); mappings.setProperty("DatabaseException", "databaseError");//數據庫異常處理 mappings.setProperty("UnauthorizedException","403"); simpleMappingExceptionResolver.setExceptionMappings(mappings); // None by default simpleMappingExceptionResolver.setDefaultErrorView("error"); // No default simpleMappingExceptionResolver.setExceptionAttribute("ex"); // Default is "exception" return simpleMappingExceptionResolver; } }
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> index <br/> <form th:action="@{/logout}" method="post"> <p><input type="submit" value="從新登陸"/></p> </form> <form th:action="@{/select}" method="get"> <p><input type="submit" value="查看"/></p> </form> <form th:action="@{/delete}" method="get"> <p><input type="submit" value="刪除"/></p> </form> </body> </html>
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"> <title>Login</title> </head> <body> 錯誤信息:<h4 th:text="${msg}"></h4> <form action="" method="post"> <p>帳號:<input type="text" name="username" value="dalaoyang"/></p> <p>密碼:<input type="text" name="password" value="123"/></p> <p><input type="submit" value="登陸"/></p> </form> </body> </html>
另外三個跳轉頁面就不貼出來了,panpan帳號登陸能夠查看和刪除,用xiaoli帳號登陸則只有查看而沒有刪除的權限,代碼見下面,sql文件在resources包下html
github代碼java
我的網站mysql