diff --git a/example/src/main/resources/shiro.ini b/example/src/main/resources/shiro.ini index b77a78d..427a11a 100644 --- a/example/src/main/resources/shiro.ini +++ b/example/src/main/resources/shiro.ini @@ -4,37 +4,41 @@ # For those that might not understand the references in this file, the # definitions are all based on the classic Mel Brooks' film "Spaceballs". ;) # ============================================================================= +[main] +myRealm = example.ExampleRealm -# ----------------------------------------------------------------------------- -# Users and their assigned roles -# -# Each line conforms to the format defined in the -# org.apache.shiro.realm.text.TextConfigurationRealm#setUserDefinitions JavaDoc -# ----------------------------------------------------------------------------- -[users] -# user 'root' with password 'secret' and the 'admin' role -root = secret, admin -# user 'guest' with the password 'guest' and the 'guest' role -guest = guest, guest -# user 'presidentskroob' with password '12345' ("That's the same combination on -# my luggage!!!" ;)), and role 'president' -presidentskroob = 12345, president -# user 'darkhelmet' with password 'ludicrousspeed' and roles 'darklord' and 'schwartz' -darkhelmet = ludicrousspeed, darklord, schwartz -# user 'lonestarr' with password 'vespa' and roles 'goodguy' and 'schwartz' -lonestarr = vespa, goodguy, schwartz +# Uncomment the below to use simple static configuration instead of a custom realm. -# ----------------------------------------------------------------------------- -# Roles with assigned permissions -# -# Each line conforms to the format defined in the -# org.apache.shiro.realm.text.TextConfigurationRealm#setRoleDefinitions JavaDoc -# ----------------------------------------------------------------------------- -[roles] -# 'admin' role has all permissions, indicated by the wildcard '*' -admin = * -# The 'schwartz' role can do anything (*) with any lightsaber: -schwartz = lightsaber:* -# The 'goodguy' role is allowed to 'drive' (action) the winnebago (type) with -# license plate 'eagle5' (instance specific id) -goodguy = winnebago:drive:eagle5 +## ----------------------------------------------------------------------------- +## Users and their assigned roles +## +## Each line conforms to the format defined in the +## org.apache.shiro.realm.text.TextConfigurationRealm#setUserDefinitions JavaDoc +## ----------------------------------------------------------------------------- +#[users] +## user 'root' with password 'secret' and the 'admin' role +#root = secret, admin +## user 'guest' with the password 'guest' and the 'guest' role +#guest = guest, guest +## user 'presidentskroob' with password '12345' ("That's the same combination on +## my luggage!!!" ;)), and role 'president' +#presidentskroob = 12345, president +## user 'darkhelmet' with password 'ludicrousspeed' and roles 'darklord' and 'schwartz' +#darkhelmet = ludicrousspeed, darklord, schwartz +## user 'lonestarr' with password 'vespa' and roles 'goodguy' and 'schwartz' +#lonestarr = vespa, goodguy, schwartz +# +## ----------------------------------------------------------------------------- +## Roles with assigned permissions +## +## Each line conforms to the format defined in the +## org.apache.shiro.realm.text.TextConfigurationRealm#setRoleDefinitions JavaDoc +## ----------------------------------------------------------------------------- +#[roles] +## 'admin' role has all permissions, indicated by the wildcard '*' +#admin = * +## The 'schwartz' role can do anything (*) with any lightsaber: +#schwartz = lightsaber:* +## The 'goodguy' role is allowed to 'drive' (action) the winnebago (type) with +## license plate 'eagle5' (instance specific id) +#goodguy = winnebago:drive:eagle5 diff --git a/example/src/main/scala/bootstrap/liftweb/Boot.scala b/example/src/main/scala/bootstrap/liftweb/Boot.scala index b4cd4bf..b81d1e2 100644 --- a/example/src/main/scala/bootstrap/liftweb/Boot.scala +++ b/example/src/main/scala/bootstrap/liftweb/Boot.scala @@ -1,6 +1,6 @@ package bootstrap.liftweb -import net.liftweb.http.LiftRules +import net.liftweb.http.{Html5Properties, LiftRules, Req} import net.liftweb.sitemap._ import shiro.Shiro import shiro.sitemap.Locs._ @@ -17,5 +17,8 @@ class Boot { Menu("Login") / "login" >> DefaultLogin >> RequireNoAuthentication ) ::: Shiro.menus: _* )) + + LiftRules.htmlProperties.default.set((r: Req) => + new Html5Properties(r.userAgent)) } } diff --git a/example/src/main/scala/example/ExampleRealm.scala b/example/src/main/scala/example/ExampleRealm.scala new file mode 100644 index 0000000..b43ece3 --- /dev/null +++ b/example/src/main/scala/example/ExampleRealm.scala @@ -0,0 +1,83 @@ +package example + +import org.apache.shiro.realm.AuthorizingRealm +import org.apache.shiro.authc._ +import org.apache.shiro.authz._ +import org.apache.shiro.authz.permission.WildcardPermission +import org.apache.shiro.subject.PrincipalCollection + +import collection.JavaConverters._ + +/** + * An example class to demonstrate setting up a custom realm in shiro. + */ +class ExampleRealm extends AuthorizingRealm { + class User(val username: String, val password: String) + + /** + * A fake DAO for storing user credentials, roles, permissions, etc. + * In practice this will probably be a db/persistence obj of some sort. + */ + object UserDAO { + // Passwords are stored plain here but in real life please at least BCrypt them like a decent human being. + private[this] val userCredentials = Map( + "root" -> "secret", + "guest" -> "guest", + "presidentskroob" -> "12345", + "darkhelmet" -> "ludicrousspeed", + "lonestarr" -> "vespa" + ) + + private[this] val userRoles = Map( + "root" -> Set("admin"), + "guest" -> Set("guest"), + "presidentskroob" -> Set("president"), + "darkhelmet" -> Set("darklord", "schwartz"), + "lonestarr" -> Set("goodguy", "schwartz") + ) + + private[this] val rolePermissions = Map( + "admin" -> Set(new WildcardPermission("*")), + "schwartz" -> Set(new WildcardPermission("lightsaber:*")), + "darklord" -> Set(new WildcardPermission("winnebago:steal:eagle5")), + // Good guys can do whatever they want with the eagle5. + "goodguy" -> Set(new WildcardPermission("winnebago:*:eagle5")) + ) + + def getUser(username: String, password: String): Option[User] = for { + pass <- userCredentials.get(username) + if (pass == password) + } yield new User(username, password) + + def getRoles(user: User): Set[String] = { + userRoles.getOrElse(user.username, Set()) + } + + def getRolePermissions(role: String): Set[WildcardPermission] = { + rolePermissions.getOrElse(role, Set()) + } + } + + // The methods from AuthorizingRealm that actually have to be implemented. + + def doGetAuthenticationInfo(token: AuthenticationToken): AuthenticationInfo = { + val userpassToken = token.asInstanceOf[UsernamePasswordToken] + val username = userpassToken.getUsername() + val password = userpassToken.getPassword() + + UserDAO.getUser(username, password.mkString("")) match { + case Some(user: User) => new SimpleAuthenticationInfo(user, user.password, "ExampleRealm") + case None => throw new AuthenticationException("Invalid credentials provided!") + } + } + + def doGetAuthorizationInfo(principals: PrincipalCollection): AuthorizationInfo = { + val roles: Set[String] = principals.asScala.flatMap(p => UserDAO.getRoles(p.asInstanceOf[User])).toSet + val permissions: Set[Permission] = roles.flatMap(r => UserDAO.getRolePermissions(r)).toSet + + val authInfo = new SimpleAuthorizationInfo(roles.asJava) + authInfo.setObjectPermissions(permissions.asJava) + + return authInfo + } +} diff --git a/example/src/main/webapp/index.html b/example/src/main/webapp/index.html index bb63339..b39df32 100644 --- a/example/src/main/webapp/index.html +++ b/example/src/main/webapp/index.html @@ -1,8 +1,21 @@ - -

Home

- - -

This content is only available for admins

-
- -
+ + + Lift Shiro + + +
+

Home

+ +
+

This content is only available for admins

+
+ +
+

Whoooooosh, you can drive the eagle5!

+
+
+

Sneaky sneaky, you can steal the eagle5!

+
+
+ + diff --git a/example/src/main/webapp/login.html b/example/src/main/webapp/login.html index 8061566..d7c62f4 100644 --- a/example/src/main/webapp/login.html +++ b/example/src/main/webapp/login.html @@ -1,10 +1,16 @@ - -

Login

- -
-

Username:

-

Password:

-

-
- -
+ + + Lift Shiro + + +
+

Login

+ +
+

Username:

+

Password:

+

+
+
+ + diff --git a/example/src/main/webapp/restricted.html b/example/src/main/webapp/restricted.html index f7e7bcc..693d0f7 100644 --- a/example/src/main/webapp/restricted.html +++ b/example/src/main/webapp/restricted.html @@ -1,3 +1,10 @@ - -

Restricted to admin

-
+ + + Lift Shiro + + +
+

Restricted to admin

+
+ + diff --git a/example/src/main/webapp/templates-hidden/default.html b/example/src/main/webapp/templates-hidden/default.html index c8f70b1..fb4a901 100644 --- a/example/src/main/webapp/templates-hidden/default.html +++ b/example/src/main/webapp/templates-hidden/default.html @@ -2,13 +2,15 @@ Lift Shiro - - -
- -
- +
+
+
+
+
+
+