Refresh

This website github.com/t2v/play2-auth/issues/54 is currently offline. Cloudflare's Always Online™ shows a snapshot of this web page from the Internet Archive's Wayback Machine. To check for the live version, click Refresh.

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Advanced usage - need to get request path and method #54

Closed
tjslone opened this issue Oct 7, 2013 · 3 comments
Closed

Advanced usage - need to get request path and method #54

tjslone opened this issue Oct 7, 2013 · 3 comments

Comments

@tjslone
Copy link

tjslone commented Oct 7, 2013

Hello, I have just started using play2-auth and it is working nicely in my app. However I want to customise my authorize function and have used the example in the read me where a user can only edit their own messages.

In my app I need to authorize a user based on their role. The roles are not hard-coded and are stored in database. I also store in the database all the server root URLS (e.g. DELETE/users).

When a user tries to use an authenticated method I look up the user's role and if that role is allowed access to the server root.

However I have not been able to get the request parameters into my authorize method without making the following modifications to play2-auth:

diff --git a/module/src/main/scala/jp/t2v/lab/play2/auth/AsyncAuth.scala b/module/src/main/scala/jp/t2v/lab/play2/auth/AsyncAuth.scala
index effeb79..5a7ad5b 100644
--- a/module/src/main/scala/jp/t2v/lab/play2/auth/AsyncAuth.scala
+++ b/module/src/main/scala/jp/t2v/lab/play2/auth/AsyncAuth.scala
@@ -40,7 +40,7 @@ trait AsyncAuth {
} recoverWith {
case _ => authenticationFailed(request).map(Left.apply)
} flatMap {

  •  case Right(user)  => authorize(user, authority) collect {
    
  •  case Right(user)  => authorize(user, authority, request) collect {
     case true => Right(user)
    

    } recoverWith {
    case _ => authorizationFailed(request).map(Left.apply)
    diff --git a/module/src/main/scala/jp/t2v/lab/play2/auth/Auth.scala b/module/src/main/scala/jp/t2v/lab/play2/auth/Auth.scala
    index 98fca52..7e398a7 100644
    --- a/module/src/main/scala/jp/t2v/lab/play2/auth/Auth.scala
    +++ b/module/src/main/scala/jp/t2v/lab/play2/auth/Auth.scala
    @@ -39,7 +39,7 @@ trait Auth {

    def authorized(authority: Authority)(implicit request: RequestHeader): Either[SimpleResult, User] = for {
    user <- restoreUser(request).toRight(Await.result(authenticationFailed(request), 10.seconds)).right

  • _ <- Either.cond(Await.result(authorize(user, authority), 10.seconds), (), Await.result(authorizationFailed(request), 10.seconds)).right

  • _ <- Either.cond(Await.result(authorize(user, authority, request), 10.seconds), (), Await.result(authorizationFailed(request), 10.seconds)).right
    } yield user

private[auth] def restoreUser(implicit request: RequestHeader): Option[User] = for {
diff --git a/module/src/main/scala/jp/t2v/lab/play2/auth/AuthConfig.scala b/module/src/main/scala/jp/t2v/lab/play2/auth/AuthConfig.scala
index 73e4a16..f04bb5b 100644
--- a/module/src/main/scala/jp/t2v/lab/play2/auth/AuthConfig.scala
+++ b/module/src/main/scala/jp/t2v/lab/play2/auth/AuthConfig.scala
@@ -26,7 +26,7 @@ trait AuthConfig {

def authorizationFailed(request: RequestHeader)(implicit context: ExecutionContext): Future[SimpleResult]

  • def authorize(user: User, authority: Authority)(implicit context: ExecutionContext): Future[Boolean]
  • def authorize(user: User, authority: Authority, request: RequestHeader)(implicit context: ExecutionContext): Future[Boolean]

lazy val idContainer: IdContainer[Id] = new CacheIdContainer[Id]

In my app I then use the following:

type Authority = (User, RequestHeader) => Future[Boolean]

def authorize(user: User, authority: Authority, request: RequestHeader)(implicit context: ExecutionContext): Future[Boolean] = authority(user,request)

Please can you tell me if this is correct way to use the request parameters inside my authorize method? If so can this change be made in a future release?

Many thanks,

Tom

@gakuzzzz
Copy link
Member

gakuzzzz commented Oct 8, 2013

Hi,

thanks for using play2-auth.
I have grasped the problem.

I want to consider this case.

@gakuzzzz
Copy link
Member

Hi Tom

I considered this problem.
I don't think that the addition of RequestHeader is good idea.

I recommend you to use following ways.
Because, handling all role in one action violates the single responsibility principle.

  • Separate action by URL role in routes. and use authority parameter.
  • If you can not separate action, you can use a custom PathBindable of role and use authority parameter.

What do you think about these ways?

Best regards,

@gakuzzzz
Copy link
Member

The reason with me negative to add RequestHeader into authroize is that authorization should be closed in the domain layer.
So you should not use RequestHeader which belongs to the presentation layer in authorize.

Alternatively you can convert request path to domain object in controller and use it as authority.

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants