Hi there!
First, let me say welcome to the Shiro community! Hopefully you'll
find that the framework (and the community) help you greatly along the
way.
Let's see if I can answer your questions inline:
> 1. I want to use a own Login implementation to stay in the JSF universum.
> I've read in the manual, that for this case I should use
> org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter. I tried do
> set it wth this configuration:
>
> ownFilter = org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter
> ownFilter.loginUrl = /login.jsf
>
> Is this correct? Because ownFilter.loginUrl = /login.jsf does not work. I
> get directed to login.jsp everytime. If I use
>
> authc.loginUrl = /login.jsf
>
> it works.
This is quite confusing to me - the 'loginUrl' property on both the
authc filter and your ownFilter come from the same superclass!
If it doesn't work the same way, it is probably a bug. Could you
please open a Jira issue with a quick sample to test with?
In the meantime, you could try setting the 'shiro.loginUrl =
/login.jsf' property alongside your filter definitions. This should
work, but it's not an ideal config mechanism since it rather conflicts
with the concept of object-based configuration that INI depends on (it
is a 'special case' - there is no 'shiro' object, which can cause
confusion).
> 2. My JSF Bean which does the login and logout looks like this:
>
> @Named
> @SessionScoped
> public class userBean implements Serializable {
>
> private Subject currentUser = SecurityUtils.getSubject();
> private String name;
> private String password;
>
> public String login() {
>
> if (!currentUser.isAuthenticated()) {
> UsernamePasswordToken token = new UsernamePasswordToken(name,
> password);
> try {
> currentUser.login(token);
> return "index.jsf?faces-redirect=true";
> } catch (UnknownAccountException uae) {
> FacesContext.getCurrentInstance().addMessage(null, new
> FacesMessage(FacesMessage.SEVERITY_ERROR, "User name does not exist",
> null));
> } catch (IncorrectCredentialsException ice) {
> FacesContext.getCurrentInstance().addMessage(null, new
> FacesMessage(FacesMessage.SEVERITY_ERROR, "Password is wrong!", null));
> } catch (AuthenticationException lae) {
> FacesContext.getCurrentInstance().addMessage(null, new
> FacesMessage(FacesMessage.SEVERITY_ERROR, "Error during Login", null));
> }
> }
> return null;
> }
>
> public String logout() {
> currentUser = SecurityUtils.getSubject();
> currentUser.logout();
> return "login.jsf?faces-redirect=true";
> }
>
> //getter setters...
> }
>
> The Login does work but is this the correct way to do it?
You should not cache the Subject instance returned from
SecurityUtils.getSubject(). Subject state can change at any time
during a Subject's lifetime with the application, even between threads
(or requests in a web application).
For example, the code above will still execute if another thread
somewhere else authenticated the Subject successfully, which is
probably not desired (the authentication state in your cached Subject
instance does not reflect the authentication state from the other
thread). The safe bet is to always acquire the Subject as you need
it.
So, if you remove the 'currentUser' class attribute and inline it
inside of your methods, you'll be good - everything else looks great.
>
> 3. What would be the correct way to use Shiro in an EJB Project?
We really should create an EJB sample application that demonstrates
this - it has just been low priority with us working towards
graduation. If you (or anyone else) would be willing to help with
this, we'd be very grateful - please contact the dev list if you're
interested.
Anyway, much of Shiro's implementation is based on the assumption that
a Subject can always be associated with the currently executing
thread. So any code can be protected by Shiro - web environment or
not.
In order for this to work properly, there must be some interception
mechanism that creates a Subject instance, binds it to the current
thread, and then cleans up the thread after the execution is complete.
In web environments, the Shiro Filter does this automatically. If in
another environment, such as responding to a Remote Method Invocation,
something else must do this 'create/bind/unbind' logic.
So if EJB calls are always made as a result of a web request - you're
100% covered - the Shiro Filter will do all that is required. If you
have non-web-initiated calls, you'll need to write something that will
do this, typically an AOP interceptor or something similar for EJB
specific mechanisms.
The good news is that if you have to do this, it is very easy - you
can use Shiro's Spring-specific SecureRemoteInvocationExecutor [1]
code as an example to get you started. If your solution is
EJB-specific, we'd be very much interested in including it in Shiro to
help others in the same situation. If you find that you need to do
this, please consider contributing it back to the project if possible.
> My goal is to login a user in the web project over a jdbc or ldap realm. But
> of course the important methods are in the ejb container and need to be
> protected.
> - So how do I use Shiro in the EJB Container?
Once the Subject is associated with a thread, AOP is one of easiest
ways of enforcing security restrictions. Then you can annotate your
EJB methods - for example:
@RequiresRole('bankEmployee')
public void openNewBankAccount() { ... }
or
@RequiresAuthentication
public CreditCardInfo getCreditCardInfo(userId) { ... }
In Shiro's source distribution, there is an AspectJ sample application
that demonstrates this - definitely see if that can be used or
manipulated for your needs.
> - Implement the realm in the ejb Project and access it in the web and the
> ejb container?
> - Are Shiro web libraries needed in an EJB Project?
Only if you want to support web-based access or calls to your EJBs.
If your EJB app is not web-based, you don't need Shiro's web module,
but you will need to ensure the Subject create/bind/unbind logic
executes somehow as described above.
Well, I hope that helps answer your questions! Please feel free to
continue to ask anything else along the way if you need to do any
coding to get Shiro to work in an EJB app - we'll definitely want to
add that to the project!
Cheers,
Les