Siêu thị PDFTải ngay đi em, trời tối mất

Thư viện tri thức trực tuyến

Kho tài liệu với 50,000+ tài liệu học thuật

© 2023 Siêu thị PDF - Kho tài liệu học thuật hàng đầu Việt Nam

Rails for Java Developers phần 10 pdf
MIỄN PHÍ
Số trang
35
Kích thước
593.1 KB
Định dạng
PDF
Lượt xem
1614

Rails for Java Developers phần 10 pdf

Nội dung xem thử

Mô tả chi tiết

AUTHORIZATION WITH THE AUTHORIZATION PLUGIN 289

With the Authorization plugin, role permissions are assigned in the con￾troller itself. Instead of using pure Ruby code, the permit code parses a

mini-language that aspires to read like a human language. For exam￾ple, the following lines in the controller will specify that only adminis￾trators can edit Quips, and mere mortals can only view them:

Download code/rails_xt/app/controllers/quips_controller.rb

READ_ACTIONS = %w(index list show)

permit 'admin or mortal', :only=>READ_ACTIONS

permit 'admin', :except=>READ_ACTIONS

As with the Acegi pattern language, we find the Authorization plugin’s

mini-language to be self-explanatory.

You can test that the authorization protections work by loading the test

fixture data into the development database. Rails has a built-in task

specifically for this purpose. From the rails_xt directory, rake db:fixtures:

load will blow away the development database and replace its contents

with the test fixtures. After loading the fixtures, you can run script/server

and navigate to /quips. If you are Quentin, you will have read/write

access, but as Aaron you will have read access only.

Both Acegi and the Authorization plugin are much more powerful than

we have shown here. Both provide the ability to associate roles with

particular objects. Acegi also has one incredible feature that we have

not seen anywhere else. Because it integrates with the web tier, with

simple method interception, and with AspectJ’s pointcuts, Acegi can

secure just about anything. Better yet, you can use the same configu￾ration and roles from end-to-end in your application. You can use the

same roles to secure web endpoints, methods, objects, and anything

you can capture in an AspectJ pointcut. For the biggest, hairiest prob￾lems out there, we would not use anything else.

The acts_as_authenticated/Authorization plugin tandem also has its

area of excellence: the tiny amount of configuration and code involved.

The amount of configuration required is an order of magnitude less

than Acegi, and it is not spread across multiple files and languages.

This parsimony extends to the implementation as well. The entire run￾time footprint of both plugins together is less than 1,000 lines of Ruby

code. Security-related code is costly to develop and maintain, so getting

a lot done in a little code is a big advantage.

TESTING AUTHENTICATION AND AUTHORIZATION 290

10.3 Testing Authentication and Authorization

When you add authn and authz support to a Rails application, you

will typically break any functional tests that are already in place. This

is because functional tests exercise all controller code, including the

filters that are used to implement security.

For example, when we added authn and authz to People and Quips in

the previous two sections, we broke every test that invoked a secure

action, for a total of fifteen broken tests.

We have two problems here. First, we would like to be able to test the

logic of the controllers separately from the security constraints. So, we

would like a set of functional tests that do not include any security

filters. Second, we would like to be able to test the security constraints

themselves. Moreover, both of these sets of tests must be easy to write.

Otherwise, busy developers won’t write them. It would be a shame to

have an application where everything was testable except security.

The acts_as_authenticated plugin includes an AuthenticatedTestHelper

module to simplify security testing. You can make AuthenticatedTes￾tHelper available to all your tests by mixing the module into TestCase

in test/test_helper.rb:

Download code/rails_xt/test/test_helper.rb

class Test::Unit::TestCase

include AuthenticatedTestHelper

AuthenticatedTestHelper adds several new test methods. One of the most

helpful is login_as. To get our tests to pass again, we can simply login_as

some account that has every necessary role. A test case’s setup method

is a perfect place to do this, since it runs before every test:

Download code/rails_xt/test/functional/people_controller_test.rb

def setup

@controller = PeopleController.new

@request = ActionController::TestRequest.new

@response = ActionController::TestResponse.new

login_as(:quentin)

end

Since our authn and authz approach stores users and roles in the

database, we also need to add the security-related tables to the test

fixture.

TESTING AUTHENTICATION AND AUTHORIZATION 291

For example, we have used role-based security for the QuipsController, so

the functional test will need to have access to users, roles, and roles_users:

Download code/rails_xt/test/functional/quips_controller_test.rb

class QuipsControllerTest < Test::Unit::TestCase

fixtures :quips, :users, :roles, :roles_users

We used the previous approach to fix the fifteen broken functional test

for QuipsController and PeopleController. The fix required five total lines of

changed code:

• Including AuthenticatedTestHelper (one line)

• Adding login_as(:quentin) to two test classes (two lines)

• Editing the fixture line for the same two test classes (two lines)

Now the functional tests are working again, so we can turn our atten￾tion to testing the security constraints themselves. The AuthenticatedTes￾tHelper includes an assert_requires_login method that checks that a par￾ticular controller invocation gets redirected to login:

Download code/rails_xt/test/functional/quips_security_test.rb

assert_requires_login do |c|

c.post :create, :quip => {}

end

Notice that this code lives in a different test class, QuipsSecurityTest in￾stead of QuipsControllerTest. We are using a separate test class because

the QuipsControllerTest always logs in as Quentin, and now we are testing

what happens when there is no login. You can also use assert_requires_

login to test that Aaron (a mortal) lacks a role that would be allowed to

create a quip:

Download code/rails_xt/test/functional/quips_security_test.rb

assert_requires_login(:aaron) do |c|

c.post :create, :quip => {}

end

The syntax is a bit twisted here, in that assert_requires_login(:aaron) actu￾ally means “Assert that logging in as Aaron isn’t enough and that you

get redirected back to login.”

Rather than testing the redirect, you might want to test that failed

logins do not change the database. AuthenticatedTestHelper provides a

nifty assert_difference method for this kind of test. assert_difference takes

three arguments: an object, a method name, and a difference (which

defaults to +1). It also expects a block of code. assert_difference calls the

Tải ngay đi em, còn do dự, trời tối mất!