Using Shiro spring boot starter 1.4.0 in Spring boot application and can't figure out how i can extract shiro principalCollection data into my thymeleaf templates to use in other expressions etc...
I store some lightweight user data in shiro and wanted to display a custom message using current users first name and last login time
for example:
<p th:text="#{welcome.lastlogin.message(${???.firstName},${???.lastLoginTime})}">..Hello, user, how are you today?..</p>
I did dump the session attribute to see what shiro is storing the principals as and i see this in session:
org.apache.shiro.subject.support.DefaultSubjectContext_PRINCIPALS_SESSION_KEY = john.doe#somewhere.com,{userID=1,firstName=John, lastName=Doe, loginAttempts=0, lastLoginTime=Mon Jan 22 09:30:47 EST 2018}
My code uses a HashMap and adds it to the principals...
Is this even possible?
edit: I guess the other option is simply not use shiro principalCollection for this purpose and put my own object in session and use it from thymeleaf instead.
Take a look at thymeleaf-extras-shiro, It might do exactly what you are looking for. Otherwise, I'm guessing you would need to use principalCollection.getPrimaryPrincipal()
Related
I have a spring boot application using spring data rest. I have a problem in providing a well read API documentation using swagger. I tried spring fox and springdoc, but each has its problems
Spring fox:
I can not change the tag name of a repository, only the description
No support for projections
No support of openAPI3 yet (this is actually not a big problem)
Springdoc (https://springdoc.org/)
I can not change neither the tag name nor the description (#Tag does not work on repos)
No support for projections
The same repo gets 3 tags e.g. books-entity-controller, books-search-controller (with methods of a parent class) and books-property-reference-controller (with unnecessary listing of /{id}/{property} urls)
Any better way? I like spring fox for not providing more than one tag, also the auto generated tag names are better e.g. Books Entity instead of books-entity-controller. But it would be better either to customize it or find a better alternative.
I recommand Spring REST Docs over Swagger. Spring REST Docs is test-driven to guarantee your API documentation is always sync with your API.
Andy's talk explains more why Spring REST Docs is more suitable than Swagger for API documentation.
You can find offical simple guide and more samples.
My Github project uses it. You can clone the repository and have a look at the generated documentation HTML /sga-booking/index.html.
Related Spring REST Docs file are
FltApiDocumentation.java
flts.adoc
BookingApiDocumentation.java
booking.adoc
If you find my Github useful, consider give it a star.
Springdoc
I can not change neither the tag name nor the description (#Tag does not work on repos)
and
The same repo gets 3 tags
You can customize it. Use the following at the controller-class level.
#Tag(name = "Name of the Tag", description = "Description of the tag")
or
#Tags(value = {
// Multiple #Tag annotations separated by comma ,
})
or the following at the method level.
#Operation(tags = {"Tag 1", "Tag 2"})
Remember:
#Tag at a class level will override the operation level tags for the particular class.
A class level tag can have only 1 value.
So if you need a controller to have multiple tags, you should isolate it in a different class that doesn't have the #Tag at the class level.
No support for projections
I have never used projections. I generally use the #JsonIgnore to eliminate the ones not needed, but depends on your use-case.
If you want to hide something from a schema, use can use the below method
#Schema(description = "Example POJO to demonstrate the hidden attribute")
class Example {
...
#Schema(hidden = true) // <--- Will be hidden from the Swagger UI completely
String exampleId;
...
}
Hope that helps. Drop a comment for any clarification.
Id like to show a page non cached, but still take advantage of outputcache. Say a admin would like to see the page updated in real time by adding a query string nocache=1 to the url, then the outputcache wouldnt show the cached version, but if the query string is left off it would. Can I do this?
The best alternative would probably be to implement a custom cache provider which, when given a certain set of parameters, does not cache the page. Here is one such example:
http://www.haneycodes.net/custom-output-caching-with-mvc3-and-net-4-0-done-right/
If you create some miscellaneous parameter and configure the output caching to varyByParam, you should be able to call it with different values each time, it should bypass the cache... However I'm not sure this would be the best way to do that. You may want to just create a separate action for the admin to access that is secured.
I am new to grails and trying to implement LDAP authentication. I was reading the official document where it says:
"There are three options for mapping LDAP attributes to UserDetails data (as specified by the grails.plugins.springsecurity.ldap.mapper.userDetailsClass config attribute) and hopefully one of those will be sufficient for your needs."
It makes it clear to use custom one but i couldn't find any information and usage about these three options. What are they and how can i use them?
They're described in section 3 on configuration: "use 'person' to create a Person, 'inetOrgPerson' to create an InetOrgPerson, or null to create an LdapUserDetailsImpl".
i have a uri such as someController/someAction?param1=aa¶m2=bb
is there some method of grails can extract controller name and action name from this uri.
or shiro has any method to detect this uri is permitted?
i have a domain Menu(name,url), and now want to get the menu list which is permitted for current user.
url such as /auth/login(may be mapping as user:login), /user/login
so 2 days ago i ask this question.
now i change the menu to (name,controller,action,param),and filter the menulist like this:
def subject = SecurityUtils.subject;
menuList.each{
if(it.permission){
def perm = shiroPermissionResolver.resolvePermission("${it.permission.controller}:${it.permission.action}")
def isPermitted = subject.isPermitted(perm)
println "$isPermitted -> ${it.permission.controller}:${it.permission.action}"
}
}
sorry for my poor english,and thanks for reply.
btw,here is another question of how to cache shiro:
how to use cache permissions in grails shiro
To proflux:
so what do u think is the better way to store menulist?
cause:
it need to show different menu to user due to their permissions.
sometime we update a webapp, but want to show menu to user later.
so we only need to change such as a menu.visible. (better than change hard code cfg or source).
we areusing extjs to show the menu(so nav plugin cant use).
Shiro uses the convention of $controller:$action for permissions. You have two options:
Use the Shiro Tags
Use the Shiro API directly
In the first case, in your GSP you can add something like:
<shiro:hasPermission permission="someController:someAction">
<g:link...>
</shiro:hasPermission>
<shiro:lacksPermission permission="someController:someAction">
No link
</shiro:lacksPermission>
Alternatively, you can use the <g:if...> tag and use the
SecurityUtils.subject.isPermitted("someController:someAction")
method to directly check if the user has the necessary permission.
For more info, check out the Grails Shiro Tag Library Source and the Shiro API docs.
I have a grails 1.2 app and I want to use declarative security in order to restrict accesses based on roles. I decided to try shiro, installed the plugin, but when I try to authenticate, the message "Invalid username and/or password" shows up in the header. I check the db entry and the user is there with the sha'ed password. No messages are shown neither in the console nor in the stacktrace file. I added "warn 'org.jsecurity'" to Config.groovy with no results. Any hints/tricks to troubleshoot this ?
I ran into this problem as well... how are you saving the password for the user? After running quick start I followed the example on the Shiro plugin page and added the code below to my bootstrap init method:
import org.apache.shiro.crypto.hash.Sha512Hash
def user = new ShiroUser(username: "user123", passwordHash: new Sha512Hash("password").toHex())
user.save()
I would attempt to login and would continue to get a login failed. So I tried
def user = new ShiroUser(username:'admin', passwordHash:new Sha256Hash("admin").toHex())
user.save()
After changing from Sha512Hash to Sha256Hash... I was able to login!
UPDATE: Just created a new app with default Shiro Plugin settings after running 'quick-start'. If you are to create a user, you are going to want to use Sha256Hash out of the box. However, you can use Sha512Hash or Sha1Hash by adding the bean to your resources.groovy file for Spring.
Example for Sha512Hash:
beans = {
bean {
credentialMatcher(Sha512CredentialsMatcher) {
storedCredentialsHexEncoded = true
}
}
}
Did you run the quick-start? Are you using the default database realm?
I would debug through the Realm you're using and see what's going on.
I can't help with the shiro troubleshooting, but if you're looking for a more powerful solution you might want to check out nimble. It's based on shiro and offers a lot of additional features and flexibility.
You can install the latest with:
grails install-plugin nimble 0.4-SNAPSHOT
nimble documentation