diff --git a/README.md b/README.md
index 4fb7d06dafb5a99fa94672914f455f126802a301..c95faf44c193598b52e68c4f489437007aae32d3 100644
--- a/README.md
+++ b/README.md
@@ -13,20 +13,21 @@
 - Binary dependencies: `sudo apt install libxml2-dev libxslt1-dev xmlsec1 libxmlsec1-dev pkg-config`
 - Python dependencies: see `requirements.txt` or `setup.py`
 - Add the app into `INSTALLED_APPS`
-- Include the app's `urls.py` into the project `urls.py` `urlpatterns`, preferably without a prefix
+- Include the `ssoauth` `urls.py` into the project `urls.py` `urlpatterns`:
+   - Without a path/prefix: youre done.
+   - With a path/prefix:
+     - Reconsider it. It's highly recommended to include `ssoauth` **without** a prefix/path to avoid issues with apps like `contrib.admin` and `wagtail` that provide their own log in pages.
+     - If you really need to use a path/prefix, make sure to set a setting `LOGIN_URL = urls.reverse_lazy("sso-login")`
 
 
 #### Development Setup
 
-- Simply use `localhost:8000/dev/` _(might change depending on your urlconf)_ for all the logging-in-out-users-groups stuff
-- To make your life easier, add the following to your project settings: 
-```python
-LOGIN_URL = urls.reverse_lazy("sso-dev")
-```
-- If you want to debug `ssoauth` or need a fully functional SSO during development for some other reason, an example is below. For additional info see the production setup section and `ssoauth.app_settings.defaults`. If you also want a working SLO during development you will need SSL for your localhost, `nginx` will be your best friend.
+- Should work with zero additional configuration.
+- You can use `localhost:8000/dev/` _(might change depending on your configuration)_ to access the dev view with all its helper features.
 
 #### Advanced development setup
-If you are not sure whether you need it: you don't need it. 
+If you are not sure whether you need it: you don't need it.
+Use this only if you want an actual SSO with SAML2. For extra details see the default settings in `ssoauth.app_settings.defaults`. You might also need SSL, try using `nginx` for it.
 
 ```python
 """ settings/dev.py """
@@ -44,8 +45,6 @@ SP_PORT = 8000
 SP_SSL = False
 
 SP_FORCE_ENTITY_ID = "dev-id-{0}-{1}".format(socket.gethostname(), os.path.dirname(os.path.dirname(__file__)))  # too many localhosts around
-
-LOGIN_URL = urls.reverse_lazy("sso-dev")  # it's "sso-login" for prod
 ```
 
 #### Overriding Log In Pages of Other Apps
@@ -128,8 +127,8 @@ openssl req -newkey rsa:16384 -x509 -days 3650 -nodes -out sp.pem -keyout sp.key
 
 #### Add an SP to an IdP
 
-- Ask somebody who knows more. Seriously.
-- Try on the test IdP before you brick the production!
+- Ask for assistance. Seriously.
+- Please try on the test IdP before you brick the production!
 - Grab your meta
   - Run your project.
   - Find meta of your SP (relative path `/saml2/meta`)
@@ -142,7 +141,6 @@ openssl req -newkey rsa:16384 -x509 -days 3650 -nodes -out sp.pem -keyout sp.key
     - `id` should be unique
     - `metadataFile` should point on your new metadata
     - edit `./conf/attribute-filter.xml`
-      - use your head
   - `systemctl restart tomcat8`
   - make sure that IDP works
     - if IDP does not work, rollback your changes and restart the IDP again
diff --git a/ssoauth/app_settings/__init__.py b/ssoauth/app_settings/__init__.py
index 6de60b5e869b15e288c21e88bab418ed72f199c4..f6c7bdcc072eb1e470467a0e475da0d29b47eb66 100644
--- a/ssoauth/app_settings/__init__.py
+++ b/ssoauth/app_settings/__init__.py
@@ -82,6 +82,10 @@ ONELOGIN_SETTINGS_OBJECT = _SET_ON_RUNTIME
 
 # helpers
 
+def sso_is_configured():
+    return bool(ONELOGIN_SETTINGS_OBJECT)
+
+
 SSO_REQUIRED = any([
     SSO_REQUIRED_IN_DEBUG and conf.settings.DEBUG,
     SSO_REQUIRED_IN_PRODUCTION and not conf.settings.DEBUG,
diff --git a/ssoauth/app_settings/defaults.py b/ssoauth/app_settings/defaults.py
index 12aad169761a93832384cd9c2ae5381ba0dc6c15..cdcb34be5a3d814373bb768d2523e4f23b9718fd 100644
--- a/ssoauth/app_settings/defaults.py
+++ b/ssoauth/app_settings/defaults.py
@@ -10,7 +10,7 @@ If you want to change something:
 
 
 """
-Settings you may want to change:
+Settings you might want to change:
 """
 
 # host and port, not what Django thinks, but what nginx serves
diff --git a/ssoauth/checks.py b/ssoauth/checks.py
index 846eab937d7ea4e032b19f6ff241ed96b2eb52d2..87b38dd9dd05f07c743b07524260d98ceacdccdf 100644
--- a/ssoauth/checks.py
+++ b/ssoauth/checks.py
@@ -109,49 +109,6 @@ def sp_host_is_not_localhost(app_configs, **kwargs):
     return errors
 
 
-@register(Tags.compatibility)
-def pretend_backend(app_configs, **kwargs):
-    errors = list()
-    pretend_expected = "django.contrib.auth.backends.ModelBackend"
-    if app_settings.PRETEND_AUTH_BACKEND != pretend_expected:
-        errors.append(Warning("Please make sure the first element of AUTHENTICATION_BACKENDS is django.contrib.auth.backends.ModelBackend; "
-                              "if you are not using this backend you need to ensure the first backend in the list knows how to get user by id/natural key"))
-    return errors
-
-
-@register(Tags.urls)
-def auth_urls_configured(app_configs, **kwargs):
-    errors = list()
-
-    def _url_from_setting(setting_name):
-        # get url based on django setting name, handles most of cases of something going wrong
-        try:
-            setting_value = getattr(conf.settings, setting_name, None)  # setting exists
-            assert urls.resolve(setting_value)  # page exists
-            return setting_value
-        except Exception as e:
-            errors.append(Warning("Failed to resolve an URL for {s}. {ec}: {e}".format(ec=e.__class__.__name__, e=str(e),s=setting_name), obj=conf.settings))
-            return None
-
-    # # default landing and logout pages
-    # # probably this part is not longer required because how the logout process works
-    # for setting_name in ("LOGIN_REDIRECT_URL", "LOGOUT_REDIRECT_URL",):
-    #     if not _url_from_setting(setting_name):
-    #         errors.append(Warning("{setting_name} is not found or invalid.".format(**locals()), obj=conf.settings,))
-
-    if app_settings.SSO_REQUIRED:
-        # login
-        login_url_needed = urls.reverse("sso-login")
-        login_url_current = _url_from_setting("LOGIN_URL")
-        if login_url_current != login_url_needed:
-            errors.append(Warning(
-                "LOGIN_URL must point on {login_url_needed}, not on {login_url_current}. Add the following to your project settings: "
-                "LOGIN_URL = urls.reverse_lazy(\"sso-login\")".format(**locals()),
-                obj=conf.settings,
-            ))
-    return errors
-
-
 @register(Tags.security)
 def session_lifetime(app_configs, **kwargs):
     errors = list()
diff --git a/ssoauth/templates/ssoauth/dev.html b/ssoauth/templates/ssoauth/dev.html
index 4409f03e94c33816f0aa6084c5bba1a88583f57c..c9d3ff984adf282201cd4d821d406bb87d52cd30 100644
--- a/ssoauth/templates/ssoauth/dev.html
+++ b/ssoauth/templates/ssoauth/dev.html
@@ -43,12 +43,12 @@
                         <button type="submit" name="local-logout" value="local-logout" class="button button-outline button-narrow">Log Out</button>
                         <p><i>Extra actions for development and debugging</i></p>
                     </div>
-                    <div class="column {% if not sso_configured %}disabled{% endif %}">
+                    <div class="column {% if not sso_is_configured %}disabled{% endif %}">
                         <h4 class="title">Production Actions</h4>
                         <a class="button button-outline button-narrow" href="{% url "sso-login" %}?next={% url "sso-dev" %}">Log In</a>
                         <a class="button button-outline button-narrow" href="{% url "sso-logout" %}">Log Out</a>
                         <a class="button button-outline button-narrow" href="{% url "sso-saml2-meta" %}" target="_blank">Meta</a>
-                        <p><i>{% if sso_configured %}These actions are used in production{% else %}Your SSO settings are a potato{% endif %}</i></p>
+                        <p><i>{% if sso_is_configured %}These actions are used in production{% else %}SSO is not configured{% endif %}</i></p>
                     </div>
                 </div>
             </form>
diff --git a/ssoauth/urls.py b/ssoauth/urls.py
index 5970e76ffb887b916d67d60d744871cf09453e40..550dc828681191f1d64f8db28a9239eba701ec57 100644
--- a/ssoauth/urls.py
+++ b/ssoauth/urls.py
@@ -3,7 +3,7 @@ from django import conf
 from . import views
 
 urlpatterns = (
-    url(r"^login/?$", views.LogInView.as_view(), name="sso-login"),
+    url(r"^(?:.*/)?login/?$", views.LogInView.as_view(), name="sso-login"),  # aggressive login pattern helps against apps that provide own login pages and forms
     url(r"^logout/?$", views.LogOutView.as_view(), name="sso-logout"),
     url(r"^logout/message/?$", views.LoggedOutLocallyView.as_view(), name="sso-logged-out-locally"),
     url(r"^logout/idp/?$", views.IdpLogoutRedirectView.as_view(), name="sso-logout-idp"),
@@ -13,6 +13,7 @@ urlpatterns = (
 )
 
 if conf.settings.DEBUG:
+    # add the dev view
     urlpatterns += (
         url(r"^dev/?$", views.DevView.as_view(), name="sso-dev"),
     )
diff --git a/ssoauth/views.py b/ssoauth/views.py
index d61f74793341e595dd49610fec4f452356751f75..b71db1ca57f3cb93f053e3465c31c53ae38b8dda 100644
--- a/ssoauth/views.py
+++ b/ssoauth/views.py
@@ -22,15 +22,19 @@ from datetime import timedelta
 
 
 class SAMLMixin:
-    """ Merges Django runtime info and settings for OneLogin toolkit """
 
-    def __init__(self, *args, **kwargs):
-        if not app_settings.ONELOGIN_SETTINGS_OBJECT:
+    @classmethod
+    def get_onelogin_auth(cls, request):
+        """ :return: that weird auth object used by the onelogin toolkit """
+        if not app_settings.sso_is_configured():
             raise exceptions.ImproperlyConfigured("SSO is not configured.")
-        super().__init__(*args, **kwargs)
+        return OneLogin_Saml2_Auth(
+            request_data=cls._get_onelogin_request_data(request),
+            old_settings=app_settings.ONELOGIN_SETTINGS_OBJECT
+        )
 
-    @staticmethod
-    def get_onelogin_request_data(request):
+    @classmethod
+    def _get_onelogin_request_data(cls, request):
         return {
             # since nginx is in the way, the settings cannot be fetched from the request
             "https": "on" if app_settings.SP_SSL else "off",
@@ -41,16 +45,9 @@ class SAMLMixin:
             "post_data": request.POST.copy(),
         }
 
-    @classmethod
-    def get_onelogin_auth(cls, request):
-        return OneLogin_Saml2_Auth(
-            request_data=cls.get_onelogin_request_data(request),
-            old_settings=app_settings.ONELOGIN_SETTINGS_OBJECT
-        )
-
 
 @method_decorator(never_cache, "dispatch")
-class LogInView(SAMLMixin, View):
+class LogInView(SAMLMixin, RedirectView):
     """
     This view initiates SSO log in.
     To change behavior for already logged in users, you can use:
@@ -58,26 +55,24 @@ class LogInView(SAMLMixin, View):
       - LogInView.as_view(already_authenticated_redirect="some-url-name")
     """
 
-    already_authenticated_403 = False  # e.g. admin redirects to login when insufficient permissions
-    already_authenticated_redirect = None
+    already_authenticated_403 = False  # raise 403 if the user is already authenticated
 
-    def get(self, request, *args, **kwargs):
-        if request.user.is_authenticated:
-            logger.warning("{u} is already authenticated and attempts to log in again.".format(u=request.user))
+    def get_redirect_url(self, *args, **kwargs):
+        if self.request.user.is_authenticated:
+            logger.info("{u} is already authenticated and attempts to log in again.".format(u=self.request.user))
             if self.already_authenticated_403:
-                logger.warning("Assuming 403 (you configured the view this way).")
-                raise exceptions.PermissionDenied()
-            if self.already_authenticated_redirect:
-                logger.warning("Redirecting (you configured the view this way).")
-                return http.HttpResponseRedirect(urls.reverse(self.already_authenticated_redirect))
-            if request.user.last_login > timezone.now() - timedelta(seconds=20):
-                # possible redirect loop (e.g. django.contrib.admin causes them)
-                logger.error("{u} is logging in too often (probably an endless redirect loop).".format(u=request.user))
+                raise exceptions.PermissionDenied("Already authenticated")
+            if self.request.user.last_login > timezone.now() - timedelta(seconds=60):
+                # most likely a redirect loop (django.contrib.admin loves to cause these)
+                logger.warning("{u} has already logged in recently. Probably a redirect loop, happens in django due to insufficient permissions to display some page.".format(u=self.request.user))
                 raise exceptions.PermissionDenied()
+        if conf.settings.DEBUG and not app_settings.sso_is_configured():
+            logger.info("SSO is not configured, redirecting to the dev view instead.")
+            return self._get_redirect_to_dev()
         # logging in
-        auth = self.get_onelogin_auth(request)
-        login = auth.login(return_to=self.get_next_url(request))
-        return http.HttpResponseRedirect(login)
+        auth = self.get_onelogin_auth(self.request)
+        idp_login_url = auth.login(return_to=self.get_next_url(self.request))
+        return idp_login_url
 
     @staticmethod
     def get_next_url(request):
@@ -85,6 +80,16 @@ class LogInView(SAMLMixin, View):
         logger.debug("Will ask IDP to redirect after login to: {}".format(next_url))
         return str(next_url)
 
+    def _get_redirect_to_dev(self):
+        redirect_to = urls.reverse("sso-dev")
+        if REDIRECT_FIELD_NAME in self.request.GET:  # preserve the next url
+            redirect_to = "{0}?{1}={2}".format(
+                redirect_to,
+                REDIRECT_FIELD_NAME,
+                self.request.GET.get(REDIRECT_FIELD_NAME)
+            )
+        return redirect_to
+
 
 @method_decorator(never_cache, "dispatch")
 class LogOutView(RedirectView):
@@ -311,7 +316,7 @@ class DevView(FormView):
             ["Session", dict(self.request.session)],
         ]
         context.update(dict(
-            sso_configured=bool(app_settings.ONELOGIN_SETTINGS_OBJECT),
+            sso_is_configured=bool(app_settings.sso_is_configured()),
             next_url=self.next_url,
         ))
         return context